Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.landawn.abacus.util.stream.EntryStream Maven / Gradle / Ivy
Go to download
A general programming library in Java/Android. It's easy to learn and simple to use with concise and powerful APIs.
/*
* Copyright (C) 2016, 2017, 2018, 2019 HaiYang Li
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.landawn.abacus.util.stream;
import java.util.AbstractMap.SimpleImmutableEntry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BiPredicate;
import java.util.function.BinaryOperator;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.stream.Collector;
import com.landawn.abacus.annotation.Beta;
import com.landawn.abacus.annotation.IntermediateOp;
import com.landawn.abacus.annotation.LazyEvaluation;
import com.landawn.abacus.annotation.ParallelSupported;
import com.landawn.abacus.annotation.SequentialOnly;
import com.landawn.abacus.annotation.TerminalOp;
import com.landawn.abacus.annotation.TerminalOpTriggered;
import com.landawn.abacus.exception.TooManyElementsException;
import com.landawn.abacus.util.AsyncExecutor;
import com.landawn.abacus.util.BiIterator;
import com.landawn.abacus.util.Comparators;
import com.landawn.abacus.util.Difference;
import com.landawn.abacus.util.Duration;
import com.landawn.abacus.util.Fn;
import com.landawn.abacus.util.If.OrElse;
import com.landawn.abacus.util.ImmutableMap;
import com.landawn.abacus.util.Indexed;
import com.landawn.abacus.util.IntList;
import com.landawn.abacus.util.Iterables;
import com.landawn.abacus.util.Joiner;
import com.landawn.abacus.util.ListMultimap;
import com.landawn.abacus.util.MergeResult;
import com.landawn.abacus.util.Multimap;
import com.landawn.abacus.util.Multiset;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.NoCachingNoUpdating.DisposableEntry;
import com.landawn.abacus.util.ObjIterator;
import com.landawn.abacus.util.Pair;
import com.landawn.abacus.util.Percentage;
import com.landawn.abacus.util.RateLimiter;
import com.landawn.abacus.util.Throwables;
import com.landawn.abacus.util.cs;
import com.landawn.abacus.util.u.Optional;
/**
* Note: This class includes codes copied from StreamEx: StreamEx under Apache License, version 2.0.
*
*
* The EntryStream class represents a stream of Map.Entry elements and supports different kinds of computations.
* The Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines.
*
*
* The Stream will be automatically closed after a terminal method is called/triggered.
*
*
* Refer to {@code com.landawn.abacus.util.stream.BaseStream} and {@code com.landawn.abacus.util.stream.Stream} for more APIs docs.
*
* @param the type of the keys in the entries of the stream
* @param the type of the values in the entries of the stream
*
* @see com.landawn.abacus.util.stream.BaseStream
* @see com.landawn.abacus.util.stream.Stream
* @see com.landawn.abacus.util.stream.Collectors
* @see com.landawn.abacus.util.Fn
* @see com.landawn.abacus.util.Comparators
*/
@com.landawn.abacus.annotation.Immutable
@LazyEvaluation
public final class EntryStream extends
StreamBase, Object[], Predicate super Map.Entry>, Consumer super Map.Entry>, Optional>, Indexed>, ObjIterator>, EntryStream> {
private static final Function, Stream>> mapper_func = Stream::of;
final Map _map; //NOSONAR
final Stream> _stream; //NOSONAR
EntryStream(final Stream extends Map.Entry extends K, ? extends V>> s) {
this(null, s);
}
@SuppressWarnings("rawtypes")
EntryStream(final Map extends K, ? extends V> m, final Stream extends Map.Entry extends K, ? extends V>> s) {
super(s.sorted, (Comparator>) s.cmp, s.closeHandlers);
_map = (Map) m;
_stream = (Stream>) s;
}
/**
* Returns a stream of the keys from the entries in this EntryStream.
*
* @return A new Stream consisting of the keys from the entries in this EntryStream.
* @see Stream#map(Function)
* @see Fn#key()
*/
@SequentialOnly
@IntermediateOp
public Stream keys() {
// It won't be parallel stream if m != null.
if (_map != null) {
return Stream.of(_map.keySet());
}
final Function, K> func = Fn.key();
if (isParallel()) {
return _stream.psp(ss -> ss.map(func));
} else {
return _stream.map(func);
}
}
/**
* Returns a stream of the values from the entries in this EntryStream.
*
* @return A new Stream consisting of the values from the entries in this EntryStream.
* @see Stream#map(Function)
* @see Fn#value()
*/
@SequentialOnly
@IntermediateOp
public Stream values() {
// It won't be parallel stream if m != null.
if (_map != null) {
return Stream.of(_map.values());
}
final Function, V> func = Fn.value();
if (isParallel()) {
return _stream.psp(ss -> ss.map(func));
} else {
return _stream.map(func);
}
}
/**
* Returns a stream of the entries in this EntryStream.
*
* @return A new Stream consisting of the entries in this EntryStream.
*/
@SequentialOnly
@IntermediateOp
public Stream> entries() {
return _stream;
}
/**
* Inverts the key-value pairs in the EntryStream.
*
* @return a new EntryStream with inverted key-value pairs
* @see #map(BiFunction)
* @see Stream#map(Function)
* @see Fn#inverse()
*/
@SequentialOnly
@IntermediateOp
public EntryStream inversed() {
final Function, Map.Entry> mapper = Fn.inverse();
if (isParallel()) {
return of(_stream.>> psp(ss -> ss.map(mapper)));
} else {
return map(mapper);
}
}
/**
* Returns a stream consisting of the elements of this stream which keys are instances of the given class.
*
* @param the type of keys to select
* @param clazz the class to filter the keys
* @return a new EntryStream with keys filtered by the specified class
* @see #filterByKey(Predicate)
*/
@SequentialOnly
@IntermediateOp
public EntryStream selectByKey(final Class clazz) {
if (isParallel()) {
//noinspection resource
return (EntryStream) sequential().filterByKey(Fn.instanceOf(clazz))
.parallel(maxThreadNum(), executorNumForVirtualThread(), splitor(), asyncExecutor(), cancelUncompletedThreads());
} else {
return (EntryStream) filterByKey(Fn.instanceOf(clazz));
}
}
/**
* Returns a stream consisting of the elements of this stream which values are instances of the given class.
*
* @param the type of values to select
* @param clazz the class to filter the values
* @return a new EntryStream with values filtered by the specified class
* @see #filterByValue(Predicate)
*/
@SequentialOnly
@IntermediateOp
public EntryStream selectByValue(final Class clazz) {
if (isParallel()) {
//noinspection resource
return (EntryStream) sequential().filterByValue(Fn.instanceOf(clazz))
.parallel(maxThreadNum(), executorNumForVirtualThread(), splitor(), asyncExecutor(), cancelUncompletedThreads());
} else {
return (EntryStream) filterByValue(Fn.instanceOf(clazz));
}
}
/**
* Filters the entries in this EntryStream based on the given predicate.
*
* @param predicate the predicate to apply to each entry to determine if it should be included
* @return a new EntryStream with entries that match the given predicate
* @see Stream#filter(Predicate)
*/
@Override
public EntryStream filter(final Predicate super Map.Entry> predicate) {
return of(_stream.filter(predicate));
}
/**
* Filters the entries in this EntryStream based on the given predicate.
*
* @param predicate the predicate to apply to each entry to determine if it should be included
* @return a new EntryStream with entries that match the given predicate
* @see Stream#filter(Predicate)
*/
@ParallelSupported
@IntermediateOp
public EntryStream filter(final BiPredicate super K, ? super V> predicate) {
return of(_stream.filter(Fn.Entries.p(predicate)));
}
/**
* Filters the entries in this EntryStream based on the given predicate.
*
* @param predicate the predicate to apply to each entry to determine if it should be included
* @param actionOnDroppedItem the action to apply to each entry that is dropped by the filter
* @return a new EntryStream with entries that match the given predicate
* @see Stream#filter(Predicate, Consumer)
*/
@Override
public EntryStream filter(final Predicate super Map.Entry> predicate, final Consumer super Map.Entry> actionOnDroppedItem) {
return of(_stream.filter(predicate, actionOnDroppedItem));
}
/**
* Filters the entries in this EntryStream based on the given key predicate.
*
* @param keyPredicate the predicate to apply to each key to determine if its entry should be included
* @return a new EntryStream with entries that match the given key predicate
* @see Stream#filter(Predicate)
*/
@ParallelSupported
@IntermediateOp
public EntryStream filterByKey(final Predicate super K> keyPredicate) {
final Predicate> predicate = Fn.testByKey(keyPredicate);
return of(_stream.filter(predicate));
}
/**
* Filters the entries in this EntryStream based on the given value predicate.
*
* @param valuePredicate the predicate to apply to each value to determine if its entry should be included
* @return a new EntryStream with entries that match the given value predicate
*/
@ParallelSupported
@IntermediateOp
public EntryStream filterByValue(final Predicate super V> valuePredicate) {
final Predicate> predicate = Fn.testByValue(valuePredicate);
return of(_stream.filter(predicate));
}
// /**
// *
// * @param
// * @param predicate
// * @return
// * @deprecated
// */
// @Deprecated
// @Override
// public EntryStream removeIf(final Predicate super Map.Entry> predicate) {
// return of(s.removeIf(predicate));
// }
//
// /**
// *
// * @param
// * @param predicate
// * @return
// * @deprecated
// */
// @ParallelSupported
// @Deprecated
// public EntryStream removeIf(final BiPredicate super K, ? super V> predicate) {
// return of(s.removeIf(Fn.Entries.p(predicate)));
// }
//
// @Deprecated
// @Override
// public EntryStream removeIf(Predicate super Map.Entry> predicate, Consumer super Map.Entry> actionOnDroppedItem) {
// return of(s.removeIf(predicate, actionOnDroppedItem));
// }
/**
* Keeps the elements until the given predicate returns {@code false}.
* The stream should be sorted, which means if x is the first element: {@code predicate.test(x)} returns {@code false}, any element y behind x: {@code predicate.test(y)} should return {@code false}.
*
* @param predicate the predicate to apply to each entry to determine if it should be included
* @return a new EntryStream with entries that match the given predicate
* @see Stream#takeWhile(Predicate)
*/
@Override
public EntryStream takeWhile(final Predicate super Map.Entry> predicate) {
return of(_stream.takeWhile(predicate));
}
/**
* Keeps the elements until the given predicate returns {@code false}.
* The stream should be sorted, which means if x is the first element: {@code predicate.test(x)} returns {@code false}, any element y behind x: {@code predicate.test(y)} should return {@code false}.
*
* @param predicate the predicate to apply to each entry to determine if it should be included
* @return a new EntryStream with entries that match the given predicate
* @see Stream#takeWhile(Predicate)
*/
@ParallelSupported
@IntermediateOp
public EntryStream takeWhile(final BiPredicate super K, ? super V> predicate) {
return of(_stream.takeWhile(Fn.Entries.p(predicate)));
}
/**
* Drops the elements from this EntryStream while the given predicate returns {@code true}.
*
* @param predicate the predicate to apply to each entry to determine if it should be dropped
* @return a new EntryStream with entries that do not match the given predicate
* @see Stream#dropWhile(Predicate)
*/
@Override
public EntryStream dropWhile(final Predicate super Map.Entry> predicate) {
return of(_stream.dropWhile(predicate));
}
/**
* Drops the elements from this EntryStream while the given predicate returns {@code true}.
*
* @param predicate the predicate to apply to each entry to determine if it should be dropped
* @return a new EntryStream with entries that do not match the given predicate
* @see Stream#dropWhile(Predicate)
*/
@ParallelSupported
@IntermediateOp
public EntryStream dropWhile(final BiPredicate super K, ? super V> predicate) {
return of(_stream.dropWhile(Fn.Entries.p(predicate)));
}
/**
* Drops the elements from this EntryStream while the given predicate returns {@code true},
* and applies the specified action to each dropped element.
*
* @param predicate the predicate to apply to each entry to determine if it should be dropped
* @param actionOnDroppedItem the action to apply to each entry that is dropped by the predicate
* @return a new EntryStream with entries that do not match the given predicate
* @see Stream#dropWhile(Predicate, Consumer)
*/
@Override
public EntryStream dropWhile(final Predicate super Map.Entry> predicate, final Consumer super Map.Entry> actionOnDroppedItem) {
return of(_stream.dropWhile(predicate, actionOnDroppedItem));
}
/**
* Skips elements from this EntryStream until the given predicate returns {@code true}.
*
* @param predicate the predicate to apply to each entry to determine if it should be skipped
* @return a new EntryStream with entries starting from the first entry that matches the given predicate
* @see Stream#skipUntil(Predicate)
*/
@Override
public EntryStream skipUntil(final Predicate super Map.Entry> predicate) {
return of(_stream.skipUntil(predicate));
}
/**
* Skips elements from this EntryStream until the given predicate returns {@code true}.
*
* @param predicate the predicate to apply to each entry to determine if it should be skipped
* @return a new EntryStream with entries starting from the first entry that matches the given predicate
* @see Stream#skipUntil(Predicate)
*/
@ParallelSupported
@IntermediateOp
public EntryStream skipUntil(final BiPredicate super K, ? super V> predicate) {
return of(_stream.skipUntil(Fn.Entries.p(predicate)));
}
/**
* Transforms the entries in this EntryStream using the given mapper function.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the function to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see Stream#map(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream map(final Function super Map.Entry, ? extends Map.Entry extends KK, ? extends VV>> mapper) {
return _stream.mapToEntry(mapper);
}
/**
* Transforms the entries in this EntryStream using the given key and value extractor functions.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param keyMapper the function to apply to each entry to extract the key
* @param valueMapper the function to apply to each entry to extract the value
* @return a new EntryStream with transformed entries
*/
@ParallelSupported
@IntermediateOp
public EntryStream map(final Function super Map.Entry, ? extends KK> keyMapper,
final Function super Map.Entry, ? extends VV> valueMapper) {
return _stream.mapToEntry(keyMapper, valueMapper);
}
/**
* Transforms the entries in this EntryStream using the given BiFunction mapper.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the BiFunction to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see #map(BiFunction)
* @see Stream#map(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream map(final BiFunction super K, ? super V, ? extends Map.Entry extends KK, ? extends VV>> mapper) {
return map(Fn.Entries.f(mapper));
}
/**
* Transforms the entries in this EntryStream using the given key and value extractor functions.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param keyMapper the function to apply to each entry to extract the key
* @param valueMapper the function to apply to each entry to extract the value
* @return a new EntryStream with transformed entries
*/
@ParallelSupported
@IntermediateOp
public EntryStream map(final BiFunction super K, ? super V, ? extends KK> keyMapper,
final BiFunction super K, ? super V, ? extends VV> valueMapper) {
final Function, Map.Entry> mapper = t -> new SimpleImmutableEntry<>(keyMapper.apply(t.getKey(), t.getValue()),
valueMapper.apply(t.getKey(), t.getValue()));
return map(mapper);
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a BiConsumer as an argument which is applied to each element in the stream and a Consumer that accepts multiple output elements.
* The result is a new stream consisting of all output elements produced by the BiConsumer for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the BiConsumer to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see Stream#mapMulti(BiConsumer)
*/
@Beta
@ParallelSupported
@IntermediateOp
public EntryStream mapMulti(final BiConsumer super Map.Entry, ? super Consumer>> mapper) {
return _stream.mapMulti(mapper).mapToEntry(Fn.identity());
}
/**
* Transforms the entries in this EntryStream using the given mapper function.
* The mapper function returns an Optional containing the transformed entry or an empty Optional if the entry should be excluded.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the function to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see Stream#mapPartial(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapPartial(final Function super Map.Entry, Optional extends Map.Entry extends KK, ? extends VV>>> mapper) {
return _stream.mapPartial(mapper).mapToEntry(Fn.identity());
}
/**
* Transforms the entries in this EntryStream using the given BiFunction mapper.
* The mapper function returns an Optional containing the transformed entry or an empty Optional if the entry should be excluded.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the BiFunction to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see #mapPartial(Function)
* @see Stream#mapPartial(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapPartial(final BiFunction super K, ? super V, Optional extends Map.Entry extends KK, ? extends VV>>> mapper) {
return mapPartial(Fn.Entries.f(mapper));
}
/**
* Transforms the keys in this EntryStream using the given key mapper function.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the function to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see Stream#map(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapKey(final Function super K, ? extends KK> keyMapper) {
final Function, Map.Entry> mapper = Fn.mapKey(keyMapper);
return map(mapper);
}
/**
* Transforms the keys in this EntryStream using the given key mapper function.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the function to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see Stream#map(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapKey(final BiFunction super K, ? super V, ? extends KK> keyMapper) {
final Function, Map.Entry> mapper = entry -> new SimpleImmutableEntry<>(keyMapper.apply(entry.getKey(), entry.getValue()),
entry.getValue());
return map(mapper);
}
/**
* Transforms the values in this EntryStream using the given value mapper function.
*
* @param the type of the values in the resulting entries
* @param valueMapper the function to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see Stream#map(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapValue(final Function super V, ? extends VV> valueMapper) {
final Function, Map.Entry> mapper = Fn.mapValue(valueMapper);
return map(mapper);
}
/**
* Transforms the values in this EntryStream using the given value mapper function.
*
* @param the type of the values in the resulting entries
* @param valueMapper the function to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see Stream#map(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapValue(final BiFunction super K, ? super V, ? extends VV> valueMapper) {
final Function, Map.Entry> mapper = entry -> new SimpleImmutableEntry<>(entry.getKey(),
valueMapper.apply(entry.getKey(), entry.getValue()));
return map(mapper);
}
/**
* Transforms the keys in this EntryStream using the given key mapper function.
* The mapper function returns an Optional containing the transformed key or an empty Optional if the key should be excluded.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the function to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see Stream#mapPartial(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapKeyPartial(final Function super K, Optional extends KK>> keyMapper) { //NOSONAR
final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null);
final Function, Map.Entry> mapper = entry -> {
final Optional extends KK> op = keyMapper.apply(entry.getKey());
return op.isPresent() ? new SimpleImmutableEntry<>(op.get(), entry.getValue()) : emptyEntry;
};
if (this.isParallel()) {
//noinspection resource
return map(mapper).psp(s -> s.filter(it -> it != emptyEntry));
} else {
//noinspection resource
return map(mapper).filter(it -> it != emptyEntry);
}
}
/**
* Transforms the keys in this EntryStream using the given key mapper function.
* The mapper function returns an Optional containing the transformed key or an empty Optional if the key should be excluded.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the function to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see Stream#mapPartial(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapKeyPartial(final BiFunction super K, ? super V, Optional extends KK>> keyMapper) { //NOSONAR
final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null);
final Function, Map.Entry> mapper = entry -> {
final Optional extends KK> op = keyMapper.apply(entry.getKey(), entry.getValue());
return op.isPresent() ? new SimpleImmutableEntry<>(op.get(), entry.getValue()) : emptyEntry;
};
if (this.isParallel()) {
//noinspection resource
return map(mapper).psp(s -> s.filter(it -> it != emptyEntry));
} else {
//noinspection resource
return map(mapper).filter(it -> it != emptyEntry);
}
}
/**
* Transforms the values in this EntryStream using the given value mapper function.
* The mapper function returns an Optional containing the transformed value or an empty Optional if the value should be excluded.
*
* @param the type of the values in the resulting entries
* @param valueMapper the function to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see Stream#mapPartial(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapValuePartial(final Function super V, Optional extends VV>> valueMapper) { //NOSONAR
final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null);
final Function, Map.Entry> mapper = entry -> {
final Optional extends VV> op = valueMapper.apply(entry.getValue());
return op.isPresent() ? new SimpleImmutableEntry<>(entry.getKey(), op.get()) : emptyEntry;
};
if (this.isParallel()) {
//noinspection resource
return map(mapper).psp(s -> s.filter(it -> it != emptyEntry));
} else {
//noinspection resource
return map(mapper).filter(it -> it != emptyEntry);
}
}
/**
* Transforms the values in this EntryStream using the given value mapper function.
* The mapper function returns an Optional containing the transformed value or an empty Optional if the value should be excluded.
*
* @param the type of the values in the resulting entries
* @param valueMapper the function to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see Stream#mapPartial(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream mapValuePartial(final BiFunction super K, ? super V, Optional extends VV>> valueMapper) { //NOSONAR
final Map.Entry emptyEntry = new SimpleImmutableEntry<>(null, null);
final Function, Map.Entry> mapper = entry -> {
final Optional extends VV> op = valueMapper.apply(entry.getKey(), entry.getValue());
return op.isPresent() ? new SimpleImmutableEntry<>(entry.getKey(), op.get()) : emptyEntry;
};
if (this.isParallel()) {
//noinspection resource
return map(mapper).psp(s -> s.filter(it -> it != emptyEntry));
} else {
//noinspection resource
return map(mapper).filter(it -> it != emptyEntry);
}
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a Function as an argument which is applied to each element in the stream.
* The result is a new EntryStream consisting of all output elements produced by the Function for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the Function to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatMap(final Function super Map.Entry, ? extends EntryStream extends KK, ? extends VV>> mapper) { //NOSONAR
return _stream.flattMapToEntry(mapper);
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a BiFunction as an argument which is applied to each element in the stream.
* The result is a new EntryStream consisting of all output elements produced by the BiFunction for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the BiFunction to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see #flatMap(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatMap(final BiFunction super K, ? super V, ? extends EntryStream extends KK, ? extends VV>> mapper) { //NOSONAR
return flatMap(Fn.Entries.f(mapper));
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a Function as an argument which is applied to each element in the stream.
* The result is a new Map consisting of all output elements produced by the Function for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the Function to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatmap(final Function super Map.Entry, ? extends Map extends KK, ? extends VV>> mapper) { //NOSONAR
return _stream.flatmapToEntry(mapper);
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a BiFunction as an argument which is applied to each element in the stream.
* The result is a new Map consisting of all output elements produced by the BiFunction for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the BiFunction to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see #flatmap(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatmap(final BiFunction super K, ? super V, ? extends Map extends KK, ? extends VV>> mapper) { //NOSONAR
return flatmap(Fn.Entries.f(mapper));
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a Function as an argument which is applied to each element in the stream.
* The result is a new Stream consisting of all output elements produced by the Function for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the Function to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
@Beta
public EntryStream flattMap(
final Function super Map.Entry, ? extends Stream extends Map.Entry extends KK, ? extends VV>>> mapper) {
return _stream.flatMapToEntry(mapper);
}
/**
* Applies a mapping operation on the stream with multiple output elements for each input element.
* It takes a BiFunction as an argument which is applied to each element in the stream.
* The result is a new Stream consisting of all output elements produced by the BiFunction for each input element.
*
* @param the type of the keys in the resulting entries
* @param the type of the values in the resulting entries
* @param mapper the BiFunction to apply to each entry to transform it
* @return a new EntryStream with transformed entries
* @see #flattMap(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
@Beta
public EntryStream flattMap(
final BiFunction super K, ? super V, ? extends Stream extends Map.Entry extends KK, ? extends VV>>> mapper) {
return flattMap(Fn.Entries.f(mapper));
}
/**
* Applies a mapping operation on the keys in this EntryStream with multiple output elements for each input key.
* It takes a Function as an argument which is applied to each key in the stream.
* The result is a new Stream consisting of all output keys produced by the Function for each input key.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the Function to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatMapKey(final Function super K, ? extends Stream extends KK>> keyMapper) {
final Function, Stream>> mapper2 = e -> keyMapper.apply(e.getKey())
.map(kk -> new SimpleImmutableEntry<>(kk, e.getValue()));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the keys in this EntryStream with multiple output elements for each input key.
* It takes a BiFunction as an argument which is applied to each key in the stream.
* The result is a new Stream consisting of all output keys produced by the BiFunction for each input key.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the BiFunction to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see #flatMapKey(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatMapKey(final BiFunction super K, ? super V, ? extends Stream extends KK>> keyMapper) {
final Function, Stream>> mapper2 = e -> keyMapper.apply(e.getKey(), e.getValue())
.map(kk -> new SimpleImmutableEntry<>(kk, e.getValue()));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the keys in this EntryStream with multiple output elements for each input key.
* It takes a Function as an argument which is applied to each key in the stream.
* The result is a new Collection consisting of all output keys produced by the Function for each input key.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the Function to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatmapKey(final Function super K, ? extends Collection extends KK>> keyMapper) { //NOSONAR
@SuppressWarnings("resource")
final Function, Stream>> mapper2 = e -> Stream.of(keyMapper.apply(e.getKey()))
.map(kk -> new SimpleImmutableEntry<>(kk, e.getValue()));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the keys in this EntryStream with multiple output elements for each input key.
* It takes a BiFunction as an argument which is applied to each key in the stream.
* The result is a new Collection consisting of all output keys produced by the BiFunction for each input key.
*
* @param the type of the keys in the resulting entries
* @param keyMapper the BiFunction to apply to each key to transform it
* @return a new EntryStream with transformed keys
* @see #flatMapKey(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatmapKey(final BiFunction super K, ? super V, ? extends Collection extends KK>> keyMapper) { //NOSONAR
@SuppressWarnings("resource")
final Function, Stream>> mapper2 = e -> Stream.of(keyMapper.apply(e.getKey(), e.getValue()))
.map(kk -> new SimpleImmutableEntry<>(kk, e.getValue()));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the values in this EntryStream with multiple output elements for each input value.
* It takes a Function as an argument which is applied to each value in the stream.
* The result is a new Stream consisting of all output values produced by the Function for each input value.
*
* @param the type of the values in the resulting entries
* @param valueMapper the Function to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatMapValue(final Function super V, ? extends Stream extends VV>> valueMapper) {
final Function, Stream>> mapper2 = e -> valueMapper.apply(e.getValue())
.map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the values in this EntryStream with multiple output elements for each input value.
* It takes a BiFunction as an argument which is applied to each value in the stream.
* The result is a new Stream consisting of all output values produced by the BiFunction for each input value.
*
* @param the type of the values in the resulting entries
* @param valueMapper the BiFunction to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see #flatMapValue(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatMapValue(final BiFunction super K, ? super V, ? extends Stream extends VV>> valueMapper) {
final Function, Stream>> mapper2 = e -> valueMapper.apply(e.getKey(), e.getValue())
.map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the values in this EntryStream with multiple output elements for each input value.
* It takes a Function as an argument which is applied to each value in the stream.
* The result is a new Collection consisting of all output values produced by the Function for each input value.
*
* @param the type of the values in the resulting entries
* @param valueMapper the Function to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatmapValue(final Function super V, ? extends Collection extends VV>> valueMapper) { //NOSONAR
@SuppressWarnings("resource")
final Function, Stream>> mapper2 = e -> Stream.of(valueMapper.apply(e.getValue()))
.map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv));
return flattMap(mapper2);
}
/**
* Applies a mapping operation on the values in this EntryStream with multiple output elements for each input value.
* It takes a BiFunction as an argument which is applied to each value in the stream.
* The result is a new Collection consisting of all output values produced by the BiFunction for each input value.
*
* @param the type of the values in the resulting entries
* @param valueMapper the BiFunction to apply to each value to transform it
* @return a new EntryStream with transformed values
* @see #flatMapValue(Function)
* @see Stream#flatMap(Function)
* @see Stream#flatmap(Function)
*/
@ParallelSupported
@IntermediateOp
public EntryStream flatmapValue(final BiFunction super K, ? super V, ? extends Collection extends VV>> valueMapper) { //NOSONAR
@SuppressWarnings("resource")
final Function, Stream>> mapper2 = e -> Stream.of(valueMapper.apply(e.getKey(), e.getValue()))
.map(vv -> new SimpleImmutableEntry<>(e.getKey(), vv));
return flattMap(mapper2);
}
/**
* Groups the entries in this EntryStream by their keys.
* The result is a new EntryStream where each key is associated with a list of values.
*
* @return a new EntryStream with keys and their associated list of values
* @see Stream#groupBy(Function, Function)
* @see Fn#key()
* @see Fn#value()
*/
@SequentialOnly
@IntermediateOp
@TerminalOpTriggered
public EntryStream> groupBy() {
final Function super Map.Entry, K> keyMapper = Fn.key();
final Function super Map.Entry, V> valueMapper = Fn.value();
if (isParallel()) {
return of(_stream.sequential()
.groupBy(keyMapper, valueMapper)
.parallel(_stream.maxThreadNum(), _stream.executorNumForVirtualThread(), _stream.splitor(), _stream.asyncExecutor(),
_stream.cancelUncompletedThreads()));
} else {
return of(_stream.groupBy(keyMapper, valueMapper));
}
}
/**
* Groups the entries in this EntryStream by their keys.
* The result is a new EntryStream where each key is associated with a list of values.
*
* @param mapFactory The supplier providing a new empty Map into which the results will be inserted.
* @return a new EntryStream with keys and their associated list of values
* @see Stream#groupBy(Function, Function, Supplier)
*/
@SequentialOnly
@IntermediateOp
@TerminalOpTriggered
public EntryStream> groupBy(final Supplier extends Map>> mapFactory) {
final Function super Map.Entry, K> keyMapper = Fn.key();
final Function super Map.Entry, V> valueMapper = Fn.value();
if (isParallel()) {
return of(_stream.sequential()
.groupBy(keyMapper, valueMapper, mapFactory)
.parallel(_stream.maxThreadNum(), _stream.executorNumForVirtualThread(), _stream.splitor(), _stream.asyncExecutor(),
_stream.cancelUncompletedThreads()));
} else {
return of(_stream.groupBy(keyMapper, valueMapper, mapFactory));
}
}
/**
* Groups the elements of the stream by applying a key mapping function and a value mapping function to each element.
* The result is an EntryStream where each entry's key is the group identifier (determined by the key mapping function),
* and the value is a list of elements that are mapped to the corresponding key by the value mapping function.
* This is an intermediate operation.
*
* @param The type of the key in the resulting Map.Entry.
* @param The type of the value in the resulting Map.Entry.
* @param keyMapper The function to be applied to each element in the stream to determine the group it belongs to.
* @param valueMapper The function to be applied to each element in the stream to determine its value in the group.
* @return A new EntryStream consisting of entries where the key is the group identifier, and the value is a list of elements that mapped to the corresponding key.
* @see Stream#groupBy(Function, Function)
*/
@ParallelSupported
@IntermediateOp
@TerminalOpTriggered
public EntryStream> groupBy(final Function super Map.Entry, ? extends KK> keyMapper,
final Function super Map.Entry, ? extends VV> valueMapper) {
return of(_stream.groupBy(keyMapper, valueMapper));
}
/**
* Groups the elements of the stream by applying a key mapping function and a value mapping function to each element.
* The result is an EntryStream where each entry's key is the group identifier (determined by the key mapping function),
* and the value is a list of elements that are mapped to the corresponding key by the value mapping function.
* This is an intermediate operation.
*
* @param The type of the key in the resulting Map.Entry.
* @param The type of the value in the resulting Map.Entry.
* @param keyMapper The function to be applied to each element in the stream to determine the group it belongs to.
* @param valueMapper The function to be applied to each element in the stream to determine its value in the group.
* @param mapFactory The supplier providing a new empty Map into which the results will be inserted.
* @return A new EntryStream consisting of entries where the key is the group identifier, and the value is a list of elements that mapped to the corresponding key.
* @see Stream#groupBy(Function, Function, Supplier)
*/
@ParallelSupported
@IntermediateOp
@TerminalOpTriggered
public EntryStream> groupBy(final Function super Map.Entry, ? extends KK> keyMapper,
final Function super Map.Entry, ? extends VV> valueMapper, final Supplier extends Map>> mapFactory) {
return of(_stream.groupBy(keyMapper, valueMapper, mapFactory));
}
/**
* Groups the entries in this EntryStream by their keys.
* The result is a new EntryStream where each key is associated with the result of the downstream collector.
*
* @param the type of the result of the downstream collector
* @param downstream the collector to use for grouping the entries
* @return a new EntryStream with keys and their associated collected results
* @see Stream#groupBy(Function, Collector)
*/
@ParallelSupported
@IntermediateOp
@TerminalOpTriggered
public EntryStream groupBy(final Collector super Map.Entry, ?, D> downstream) {
final Function super Map.Entry, K> keyMapper = Fn.key();
return of(_stream.groupBy(keyMapper, downstream));
}
/**
* Groups the entries in this EntryStream by their keys.
* The result is a new EntryStream where each key is associated with the result of the downstream collector.
*
* @param the type of the result of the downstream collector
* @param downstream the collector to use for grouping the entries
* @param mapFactory The supplier providing a new empty Map into which the results will be inserted.
* @return a new EntryStream with keys and their associated collected results
* @see Stream#groupBy(Function, Collector, Supplier)
*/
@ParallelSupported
@IntermediateOp
@TerminalOpTriggered
public EntryStream groupBy(final Collector super Map.Entry, ?, D> downstream, final Supplier extends Map> mapFactory) {
final Function super Map.Entry, K> keyMapper = Fn.key();
return of(_stream.groupBy(keyMapper, downstream, mapFactory));
}
/**
* Groups the elements of the stream by applying a key mapping function to each element.
* The result is an EntryStream where each entry's key is the group identifier (determined by the key mapping function),
* and the value is the result of the downstream collector.
*
* @param The type of the key in the resulting Map.Entry.
* @param The type of the result of the downstream collector.
* @param keyMapper The function to be applied to each element in the stream to determine the group it belongs to.
* @param downstream The collector to use for grouping the entries.
* @return A new EntryStream consisting of entries where the key is the group identifier and the value is the result of the downstream collector.
* @see Stream#groupBy(Function, Collector)
*/
@ParallelSupported
@IntermediateOp
@TerminalOpTriggered
public EntryStream groupBy(final Function super Map.Entry, ? extends KK> keyMapper,
final Collector super Map.Entry