functionalj.stream.Streamable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of functionalj-core Show documentation
Show all versions of functionalj-core Show documentation
The module for FunctionalJ Core.
// ============================================================================
// Copyright (c) 2017-2019 Nawapunth Manusitthipol (NawaMan - http://nawaman.net).
// ----------------------------------------------------------------------------
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ============================================================================
package functionalj.stream;
import static functionalj.function.Func.themAll;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
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.function.UnaryOperator;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import functionalj.function.Func0;
import functionalj.function.Func1;
import functionalj.function.Func2;
import functionalj.function.Func3;
import functionalj.function.Func4;
import functionalj.function.Func5;
import functionalj.function.Func6;
import functionalj.functions.StrFuncs;
import functionalj.lens.lenses.AnyLens;
import functionalj.list.FuncList;
import functionalj.list.ImmutableList;
import functionalj.map.FuncMap;
import functionalj.map.ImmutableMap;
import functionalj.pipeable.Pipeable;
import functionalj.promise.UncompleteAction;
import functionalj.result.Result;
import functionalj.tuple.Tuple;
import functionalj.tuple.Tuple2;
import functionalj.tuple.Tuple3;
import functionalj.tuple.Tuple4;
import functionalj.tuple.Tuple5;
import functionalj.tuple.Tuple6;
import lombok.val;
class Helper {
static FuncList> segmentByPercentiles(FuncList list, FuncList percentiles) {
val size = list.size();
val indexes = percentiles.sorted().map(d -> (int)Math.round(d*size/100)).toArrayList();
if (indexes.get(indexes.size() - 1) != size) {
indexes.add(size);
}
val lists = new ArrayList>();
for (int i = 0; i < indexes.size(); i++) {
lists.add(new ArrayList());
}
int idx = 0;
for (int i = 0; i < size; i++) {
if (i >= indexes.get(idx)) {
idx++;
}
val l = lists.get(idx);
val element = list.get(i);
l.add(element);
}
return FuncList.from(
lists
.stream()
.map(each -> (FuncList)StreamPlus.from(each.stream()).toImmutableList()));
}
//
// static FuncList> toPercentilesOf(int size, FuncList> list) {
// val sorted
// = list
// .mapWithIndex((index, tuper) -> Tuple.of(tuper._1(), tuper._2(), index*100.0/size))
// .sortedBy(tuple -> tuple._1());
// FuncList> results = sorted
// .map(tuple -> Tuple.of(tuple._2(), tuple._3()));
// return results;
// }
}
@SuppressWarnings("javadoc")
@FunctionalInterface
public interface Streamable extends StreamableWithGet {
@SafeVarargs
public static Streamable of(D ... data) {
return ()->StreamPlus.from(Stream.of(data));
}
public static Streamable from(Collection collection) {
return ()->StreamPlus.from(collection.stream());
}
public static Streamable from(Func0> supplier) {
return ()->StreamPlus.from(supplier.get());
}
@SafeVarargs
public static Streamable cycle(D ... data) {
return ()->StreamPlus.cycle(data);
}
public static Streamable loop(int time) {
return ()->StreamPlus.loop(time);
}
public static Streamable loop() {
return ()->StreamPlus.loop();
}
public static Streamable infiniteInt() {
return ()->StreamPlus.infiniteInt();
}
public static Streamable range(int startInclusive, int endExclusive) {
return ()->StreamPlus.range(startInclusive, endExclusive);
}
public static Streamable empty() {
return ()->StreamPlus.empty();
}
// Because people know this.
@SafeVarargs
public static Streamable concat(Streamable ... streams) {
return ()->StreamPlus.of(streams).flatMap(s -> s.stream());
}
// To avoid name conflict with String.concat
@SafeVarargs
public static Streamable combine(Streamable ... streams) {
return ()->StreamPlus.of(streams).flatMap(s -> s.stream());
}
public static Streamable generate(Supplier> supplier) {
return ()->StreamPlus.generate(supplier.get());
}
public static Streamable generateBy(Supplier> supplier) {
return ()->StreamPlus.generate(supplier.get());
}
public static Streamable iterate(D seed, UnaryOperator f) {
return ()->StreamPlus.iterate(seed, f);
}
public static Streamable compound(D seed, UnaryOperator f) {
return ()->StreamPlus.compound(seed, f);
}
public static Streamable iterate(D seed1, D seed2, BinaryOperator f) {
return ()->{
AtomicInteger counter = new AtomicInteger(0);
AtomicReference d1 = new AtomicReference(seed1);
AtomicReference d2 = new AtomicReference(seed2);
return StreamPlus.generate(()->{
if (counter.getAndIncrement() == 0)
return seed1;
if (counter.getAndIncrement() == 2)
return seed2;
D i2 = d2.get();
D i1 = d1.getAndSet(i2);
D i = f.apply(i1, i2);
d2.set(i);
return i;
});
};
}
public static Streamable with(Streamable source, Function, Stream> action) {
return new Streamable() {
@Override
public StreamPlus stream() {
val sourceStream = source.stream();
val targetStream = action.apply(sourceStream);
return StreamPlus.from(targetStream);
}
};
}
public static Streamable from(Streamable source, Function, Stream> action) {
return new Streamable() {
@Override
public StreamPlus stream() {
val targetStream = action.apply(source);
return StreamPlus.from(targetStream);
}
};
}
public StreamPlus stream();
public default Streamable deriveWith(Function, Stream> action) {
return Streamable.with(this, action);
}
public default Streamable deriveFrom(Function, Stream> action) {
return Streamable.from(this, action);
}
public default Pipeable> pipable() {
return Pipeable.of(this);
}
public default Streamable map(Function super DATA, ? extends TARGET> mapper) {
return deriveWith(stream -> {
return stream.map(mapper);
});
}
public default Streamable flatMap(Function super DATA, ? extends Streamable extends TARGET>> mapper) {
return deriveWith(stream -> {
return stream.flatMap(e -> mapper.apply(e).stream());
});
}
public default Streamable filter(Predicate super DATA> predicate) {
return deriveWith(stream -> {
return (predicate == null)
? stream
: stream.filter(predicate);
});
}
public default Streamable peek(Consumer super DATA> action) {
return deriveWith(stream -> {
return (action == null)
? stream
: stream.peek(action);
});
}
//-- Limit/Skip --
public default Streamable limit(long maxSize) {
return deriveWith(stream -> {
return stream.limit(maxSize);
});
}
public default Streamable skip(long n) {
return deriveWith(stream -> {
return stream.skip(n);
});
}
public default Streamable skipWhile(Predicate super DATA> condition) {
return deriveWith(stream -> {
return StreamPlus.from(stream).skipWhile(condition);
});
}
public default Streamable skipUntil(Predicate super DATA> condition) {
return deriveWith(stream -> {
return StreamPlus.from(stream).skipUntil(condition);
});
}
public default Streamable takeWhile(Predicate super DATA> condition) {
return deriveWith(stream -> {
return StreamPlus.from(stream).takeWhile(condition);
});
}
public default Streamable takeUntil(Predicate super DATA> condition) {
return deriveWith(stream -> {
return StreamPlus.from(stream).takeUntil(condition);
});
}
public default Streamable distinct() {
return deriveWith(stream -> {
return stream.distinct();
});
}
public default Streamable sorted() {
return deriveWith(stream -> {
return stream.sorted();
});
}
public default Streamable sorted(Comparator super DATA> comparator) {
return deriveWith(stream -> {
return (comparator == null)
? stream.sorted()
: stream.sorted(comparator);
});
}
public default Streamable limit(Long maxSize) {
return deriveWith(stream -> {
return ((maxSize == null) || (maxSize.longValue() < 0))
? stream
: stream.limit(maxSize);
});
}
public default Streamable skip(Long startAt) {
return deriveWith(stream -> {
return ((startAt == null) || (startAt.longValue() < 0))
? stream
: stream.skip(startAt);
});
}
//-- Sorted --
public default > Streamable sortedBy(Function super DATA, T> mapper) {
return deriveWith(stream -> {
return stream.sorted((a, b) -> {
T vA = mapper.apply(a);
T vB = mapper.apply(b);
return vA.compareTo(vB);
});
});
}
public default Streamable sortedBy(Function super DATA, T> mapper, Comparator comparator) {
return deriveWith(stream -> {
return stream.sorted((a, b) -> {
T vA = mapper.apply(a);
T vB = mapper.apply(b);
return Objects.compare(vA, vB, comparator);
});
});
}
// -- fillNull --
public default Streamable fillNull(AnyLens lens, VALUE replacement) {
return deriveWith(stream -> StreamPlus.from(stream).fillNull(lens, replacement));
}
public default Streamable fillNull(
Func1 get,
Func2 set,
VALUE replacement) {
return deriveWith(stream -> StreamPlus.from(stream).fillNull(get, set, replacement));
}
public default Streamable fillNull(
AnyLens lens,
Supplier replacementSupplier) {
return deriveWith(stream -> StreamPlus.from(stream).fillNull(lens, replacementSupplier));
}
public default Streamable fillNull(
Func1 get,
Func2 set,
Supplier replacementSupplier) {
return deriveWith(stream -> StreamPlus.from(stream).fillNull(get, set, replacementSupplier));
}
public default Streamable fillNull(
AnyLens lens,
Func1 replacementFunction) {
return deriveWith(stream -> StreamPlus.from(stream).fillNull(lens, replacementFunction));
}
public default Streamable fillNull(
Func1 get,
Func2 set,
Func1 replacementFunction) {
return deriveWith(stream -> StreamPlus.from(stream).fillNull(get, set, replacementFunction));
}
//--map with condition --
public default Streamable mapOnly(Predicate super DATA> checker, Function super DATA, DATA> mapper) {
return map(d -> checker.test(d) ? mapper.apply(d) : d);
}
public default Streamable mapIf(
Predicate super DATA> checker,
Function super DATA, T> mapper,
Function super DATA, T> elseMapper) {
return deriveWith(stream -> StreamPlus.from(stream).mapIf(checker, mapper, elseMapper));
}
public default Streamable mapFirst(
Function super DATA, T> mapper1,
Function super DATA, T> mapper2) {
return deriveWith(stream -> StreamPlus.from(stream).mapFirst(mapper1, mapper2));
}
public default Streamable mapFirst(
Function super DATA, T> mapper1,
Function super DATA, T> mapper2,
Function super DATA, T> mapper3) {
return deriveWith(stream -> StreamPlus.from(stream).mapFirst(mapper1, mapper2, mapper3));
}
public default Streamable mapFirst(
Function super DATA, T> mapper1,
Function super DATA, T> mapper2,
Function super DATA, T> mapper3,
Function super DATA, T> mapper4) {
return deriveWith(stream -> StreamPlus.from(stream).mapFirst(mapper1, mapper2, mapper3, mapper4));
}
public default Streamable mapFirst(
Function super DATA, T> mapper1,
Function super DATA, T> mapper2,
Function super DATA, T> mapper3,
Function super DATA, T> mapper4,
Function super DATA, T> mapper5) {
return deriveWith(stream -> StreamPlus.from(stream).mapFirst(mapper1, mapper2, mapper3, mapper4, mapper5));
}
public default Streamable mapFirst(
Function super DATA, T> mapper1,
Function super DATA, T> mapper2,
Function super DATA, T> mapper3,
Function super DATA, T> mapper4,
Function super DATA, T> mapper5,
Function super DATA, T> mapper6) {
return deriveWith(stream -> StreamPlus.from(stream).mapFirst(mapper1, mapper2, mapper3, mapper4, mapper5, mapper6));
}
//-- mapWithIndex --
public default Streamable> mapWithIndex() {
val index = new AtomicInteger();
return map(each -> Tuple2.of(index.getAndIncrement(), each));
}
public default Streamable mapWithIndex(BiFunction super Integer, ? super DATA, T> mapper) {
return deriveWith(stream -> {
val index = new AtomicInteger();
return stream.map(each -> mapper.apply(index.getAndIncrement(), each));
});
}
public default Streamable mapWithIndex(
Function super DATA, ? extends T1> mapper1,
BiFunction super Integer, ? super T1, T> mapper) {
return deriveWith(stream -> {
val index = new AtomicInteger();
return stream.map(each -> mapper.apply(
index.getAndIncrement(),
mapper1.apply(each)));
});
}
//-- mapWithPrev --
public default Streamable mapWithPrev(BiFunction super Result, ? super DATA, ? extends TARGET> mapper) {
return deriveWith(stream -> {
val prev = new AtomicReference>(Result.ofNotExist());
return map(element -> {
val newValue = mapper.apply(prev.get(), element);
prev.set(Result.valueOf(element));
return newValue;
})
.stream();
});
}
// -- accumulate --
public default Streamable accumulate(BiFunction super DATA, ? super DATA, ? extends DATA> accumulator) {
return deriveWith(stream -> {
val iterator = StreamPlus.from(stream).iterator();
if (!iterator.hasNext())
return StreamPlus.empty();
val prev = new AtomicReference(iterator.next());
return StreamPlus.concat(
StreamPlus.of(prev.get()),
iterator.stream().map(n -> {
val next = accumulator.apply(n, prev.get());
prev.set(next);
return next;
})
);
});
}
public default Streamable restate(BiFunction super DATA, Streamable, Streamable> restater) {
val func = (UnaryOperator>>)((Tuple2> pair) -> {
val stream = pair._2();
val iterator = stream.iterator();
if (!iterator.hasNext())
return null;
val head = iterator.next();
val tail =restater.apply(head, ()->iterator.stream());
return Tuple2.of(head, tail);
});
val seed = Tuple2.of((DATA)null, this);
val endStream = (Streamable)(()->StreamPlus.iterate(seed, func).takeUntil(t -> t == null).skip(1).map(t -> t._1()));
return endStream;
}
//== Map to tuple. ==
// ++ Generated with: GeneratorFunctorMapToTupleToObject ++
public default
Streamable> mapTuple(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2) {
return mapThen(mapper1, mapper2,
(v1, v2) -> Tuple2.of(v1, v2));
}
public default
Streamable> mapTuple(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3) {
return mapThen(mapper1, mapper2, mapper3,
(v1, v2, v3) -> Tuple3.of(v1, v2, v3));
}
public default
Streamable> mapTuple(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Function super DATA, ? extends T4> mapper4) {
return mapThen(mapper1, mapper2, mapper3, mapper4,
(v1, v2, v3, v4) -> Tuple4.of(v1, v2, v3, v4));
}
public default
Streamable> mapTuple(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Function super DATA, ? extends T4> mapper4,
Function super DATA, ? extends T5> mapper5) {
return mapThen(mapper1, mapper2, mapper3, mapper4, mapper5,
(v1, v2, v3, v4, v5) -> Tuple5.of(v1, v2, v3, v4, v5));
}
public default
Streamable> mapTuple(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Function super DATA, ? extends T4> mapper4,
Function super DATA, ? extends T5> mapper5,
Function super DATA, ? extends T6> mapper6) {
return mapThen(mapper1, mapper2, mapper3, mapper4, mapper5, mapper6,
(v1, v2, v3, v4, v5, v6) -> Tuple6.of(v1, v2, v3, v4, v5, v6));
}
//-- Map and combine --
public default
Streamable mapThen(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
BiFunction function) {
return map(each -> {
val v1 = mapper1.apply(each);
val v2 = mapper2.apply(each);
val v = function.apply(v1, v2);
return v;
});
}
public default
Streamable mapThen(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Func3 function) {
return map(each -> {
val v1 = mapper1.apply(each);
val v2 = mapper2.apply(each);
val v3 = mapper3.apply(each);
val v = function.apply(v1, v2, v3);
return v;
});
}
public default
Streamable mapThen(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Function super DATA, ? extends T4> mapper4,
Func4 function) {
return map(each -> {
val v1 = mapper1.apply(each);
val v2 = mapper2.apply(each);
val v3 = mapper3.apply(each);
val v4 = mapper4.apply(each);
val v = function.apply(v1, v2, v3, v4);
return v;
});
}
public default
Streamable mapThen(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Function super DATA, ? extends T4> mapper4,
Function super DATA, ? extends T5> mapper5,
Func5 function) {
return map(each -> {
val v1 = mapper1.apply(each);
val v2 = mapper2.apply(each);
val v3 = mapper3.apply(each);
val v4 = mapper4.apply(each);
val v5 = mapper5.apply(each);
val v = function.apply(v1, v2, v3, v4, v5);
return v;
});
}
public default
Streamable mapThen(
Function super DATA, ? extends T1> mapper1,
Function super DATA, ? extends T2> mapper2,
Function super DATA, ? extends T3> mapper3,
Function super DATA, ? extends T4> mapper4,
Function super DATA, ? extends T5> mapper5,
Function super DATA, ? extends T6> mapper6,
Func6 function) {
return map(each -> {
val v1 = mapper1.apply(each);
val v2 = mapper2.apply(each);
val v3 = mapper3.apply(each);
val v4 = mapper4.apply(each);
val v5 = mapper5.apply(each);
val v6 = mapper6.apply(each);
val v = function.apply(v1, v2, v3, v4, v5, v6);
return v;
});
}
// -- Generated with: GeneratorFunctorMapToTupleToObject --
public default Streamable> mapToMap(
KEY key, Function super DATA, ? extends VALUE> mapper) {
return map(data -> ImmutableMap.of(key, mapper.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4,
KEY key5, Function super DATA, ? extends VALUE> mapper5) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data),
key5, mapper5.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4,
KEY key5, Function super DATA, ? extends VALUE> mapper5,
KEY key6, Function super DATA, ? extends VALUE> mapper6) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data),
key5, mapper5.apply(data),
key6, mapper6.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4,
KEY key5, Function super DATA, ? extends VALUE> mapper5,
KEY key6, Function super DATA, ? extends VALUE> mapper6,
KEY key7, Function super DATA, ? extends VALUE> mapper7) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data),
key5, mapper5.apply(data),
key6, mapper6.apply(data),
key7, mapper7.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4,
KEY key5, Function super DATA, ? extends VALUE> mapper5,
KEY key6, Function super DATA, ? extends VALUE> mapper6,
KEY key7, Function super DATA, ? extends VALUE> mapper7,
KEY key8, Function super DATA, ? extends VALUE> mapper8) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data),
key5, mapper5.apply(data),
key6, mapper6.apply(data),
key7, mapper7.apply(data),
key8, mapper8.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4,
KEY key5, Function super DATA, ? extends VALUE> mapper5,
KEY key6, Function super DATA, ? extends VALUE> mapper6,
KEY key7, Function super DATA, ? extends VALUE> mapper7,
KEY key8, Function super DATA, ? extends VALUE> mapper8,
KEY key9, Function super DATA, ? extends VALUE> mapper9) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data),
key5, mapper5.apply(data),
key6, mapper6.apply(data),
key7, mapper7.apply(data),
key8, mapper8.apply(data),
key9, mapper9.apply(data)));
}
public default Streamable> mapToMap(
KEY key1, Function super DATA, ? extends VALUE> mapper1,
KEY key2, Function super DATA, ? extends VALUE> mapper2,
KEY key3, Function super DATA, ? extends VALUE> mapper3,
KEY key4, Function super DATA, ? extends VALUE> mapper4,
KEY key5, Function super DATA, ? extends VALUE> mapper5,
KEY key6, Function super DATA, ? extends VALUE> mapper6,
KEY key7, Function super DATA, ? extends VALUE> mapper7,
KEY key8, Function super DATA, ? extends VALUE> mapper8,
KEY key9, Function super DATA, ? extends VALUE> mapper9,
KEY key10, Function super DATA, ? extends VALUE> mapper10) {
return map(data -> ImmutableMap.of(
key1, mapper1.apply(data),
key2, mapper2.apply(data),
key3, mapper3.apply(data),
key4, mapper4.apply(data),
key5, mapper5.apply(data),
key6, mapper6.apply(data),
key7, mapper7.apply(data),
key8, mapper8.apply(data),
key9, mapper9.apply(data),
key10, mapper10.apply(data)));
}
//-- Filter --
public default Streamable filterNonNull() {
return deriveWith(stream -> stream.filter(Objects::nonNull));
}
public default Streamable filterIn(Collection super DATA> collection) {
return deriveWith(stream -> {
return (collection == null)
? Stream.empty()
: stream.filter(data -> collection.contains(data));
});
}
public default Streamable exclude(Predicate super DATA> predicate) {
return deriveWith(stream -> {
return (predicate == null)
? stream
: stream.filter(data -> !predicate.test(data));
});
}
public default Streamable excludeIn(Collection super DATA> collection) {
return deriveWith(stream -> {
return (collection == null)
? stream
: stream.filter(data -> !collection.contains(data));
});
}
public default Streamable filter(Class clzz) {
return filter(clzz::isInstance);
}
public default Streamable filter(Class clzz, Predicate super T> theCondition) {
return filter(value -> {
if (!clzz.isInstance(value))
return false;
val target = clzz.cast(value);
val isPass = theCondition.test(target);
return isPass;
});
}
public default Streamable filter(Function super DATA, T> mapper, Predicate super T> theCondition) {
return filter(value -> {
val target = mapper.apply(value);
val isPass = theCondition.test(target);
return isPass;
});
}
public default Streamable filterWithIndex(BiFunction super Integer, ? super DATA, Boolean> predicate) {
val index = new AtomicInteger();
return filter(each -> {
return (predicate != null)
&& predicate.apply(index.getAndIncrement(), each);
});
}
//-- Peek --
public default Streamable peek(Class clzz, Consumer super T> theConsumer) {
return peek(value -> {
if (!clzz.isInstance(value))
return;
val target = clzz.cast(value);
theConsumer.accept(target);
});
}
public default Streamable peek(Predicate super DATA> selector, Consumer super DATA> theConsumer) {
return peek(value -> {
if (!selector.test(value))
return;
theConsumer.accept(value);
});
}
public default Streamable peek(Function super DATA, T> mapper, Consumer super T> theConsumer) {
return peek(value -> {
val target = mapper.apply(value);
theConsumer.accept(target);
});
}
public default Streamable peek(Function super DATA, T> mapper, Predicate super T> selector, Consumer super T> theConsumer) {
return peek(value -> {
val target = mapper.apply(value);
if (selector.test(target))
theConsumer.accept(target);
});
}
//-- FlatMap --
public default Streamable flatMapOnly(Predicate super DATA> checker, Function super DATA, ? extends Streamable> mapper) {
return flatMap(d -> checker.test(d) ? mapper.apply(d) :()-> StreamPlus.of(d));
}
public default Streamable flatMapIf(
Predicate super DATA> checker,
Function super DATA, Streamable> mapper,
Function super DATA, Streamable> elseMapper) {
return flatMap(d -> checker.test(d) ? mapper.apply(d) : elseMapper.apply(d));
}
//-- segment --
public default Streamable> segment(int count) {
return deriveWith(stream -> {
return StreamPlus.from(stream).segment(count);
});
}
public default Streamable> segment(int count, boolean includeTail) {
return deriveWith(stream -> {
return StreamPlus.from(stream).segment(count, includeTail);
});
}
public default Streamable> segment(Predicate startCondition) {
return deriveWith(stream -> {
return StreamPlus.from(stream).segment(startCondition);
});
}
public default Streamable> segment(Predicate startCondition, boolean includeTail) {
return deriveWith(stream -> {
return StreamPlus.from(stream).segment(startCondition, includeTail);
});
}
public default Streamable> segment(Predicate startCondition, Predicate endCondition) {
return deriveWith(stream -> {
return StreamPlus.from(stream).segment(startCondition, endCondition);
});
}
public default Streamable> segment(Predicate startCondition, Predicate endCondition, boolean includeLast) {
return deriveWith(stream -> {
return StreamPlus.from(stream).segment(startCondition, endCondition, includeLast);
});
}
public default Streamable> segmentByPercentiles(int ... percentiles) {
val percentileList = IntStreamPlus.of(percentiles).mapToObj(Double::valueOf).toImmutableList();
return segmentByPercentiles(percentileList);
}
public default Streamable> segmentByPercentiles(double ... percentiles) {
val percentileList = DoubleStreamPlus.of(percentiles).mapToObj(Double::valueOf).toImmutableList();
return segmentByPercentiles(percentileList);
}
public default FuncList> segmentByPercentiles(FuncList percentiles) {
val list = sorted().toImmutableList();
return Helper.segmentByPercentiles(list, percentiles);
}
public default > FuncList> segmentByPercentiles(Function super DATA, T> mapper, int ... percentiles) {
val percentileList = IntStreamPlus.of(percentiles).mapToObj(Double::valueOf).toImmutableList();
return segmentByPercentiles(mapper, percentileList);
}
public default FuncList> segmentByPercentiles(Function super DATA, T> mapper, Comparator