diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java index 05ab42fa1..5de688e5c 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/EasyStream.java @@ -9,41 +9,15 @@ import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjUtil; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.Spliterator; -import java.util.Spliterators; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; -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.function.*; 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 java.util.stream.StreamSupport; @@ -82,21 +56,19 @@ import java.util.stream.StreamSupport; * @see java.util.stream.Stream * @since 6.0.0 */ -public class EasyStream implements Stream, Iterable { +public class EasyStream extends StreamWrapper> implements Stream, Iterable { /** * 代表不存在的下标, 一般用于并行流的下标, 或者未找到元素时的下标 */ private static final int NOT_FOUND_INDEX = -1; - protected final Stream stream; - /** * 构造 * * @param stream {@link Stream} */ EasyStream(final Stream stream) { - this.stream = null == stream ? Stream.empty() : stream; + super(ObjUtil.isNull(stream) ? Stream.empty() : stream); } // region Static method @@ -280,18 +252,6 @@ public class EasyStream implements Stream, Iterable { // --------------------------------------------------------------- Static method end // endregion - /** - * 过滤元素,返回与指定断言匹配的元素组成的流 - * 这是一个无状态中间操作 - * - * @param predicate 断言 - * @return 返回叠加过滤操作后的流 - */ - @Override - public EasyStream filter(final Predicate predicate) { - return new EasyStream<>(stream.filter(predicate)); - } - /** * 过滤元素,返回与 指定操作结果 匹配 指定值 的元素组成的流 * 这是一个无状态中间操作 @@ -414,42 +374,6 @@ public class EasyStream implements Stream, Iterable { } } - /** - * 和{@link EasyStream#map(Function)}一样,只不过函数的返回值必须为int类型 - * 这是一个无状态中间操作 - * - * @param mapper 返回值为int类型的函数 - * @return 叠加操作后元素类型全为int的流 - */ - @Override - public IntStream mapToInt(final ToIntFunction mapper) { - return stream.mapToInt(mapper); - } - - /** - * 和{@link EasyStream#map(Function)}一样,只不过函数的返回值必须为long类型 - * 这是一个无状态中间操作 - * - * @param mapper 返回值为long类型的函数 - * @return 叠加操作后元素类型全为long的流 - */ - @Override - public LongStream mapToLong(final ToLongFunction mapper) { - return stream.mapToLong(mapper); - } - - /** - * 和{@link EasyStream#map(Function)}一样,只不过函数的返回值必须为double类型 - * 这是一个无状态中间操作 - * - * @param mapper 返回值为double类型的函数 - * @return 叠加操作后元素类型全为double的流 - */ - @Override - public DoubleStream mapToDouble(final ToDoubleFunction mapper) { - return stream.mapToDouble(mapper); - } - /** * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作, 转换为迭代器元素, * 最后返回所有迭代器的所有元素组成的流
@@ -483,42 +407,6 @@ public class EasyStream implements Stream, Iterable { return nonNull().flat(mapper).nonNull(); } - /** - * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流 - * 这是一个无状态中间操作 - * - * @param mapper 操作,返回IntStream - * @return 返回叠加拆分操作后的IntStream - */ - @Override - public IntStream flatMapToInt(final Function mapper) { - return stream.flatMapToInt(mapper); - } - - /** - * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流 - * 这是一个无状态中间操作 - * - * @param mapper 操作,返回LongStream - * @return 返回叠加拆分操作后的LongStream - */ - @Override - public LongStream flatMapToLong(final Function mapper) { - return stream.flatMapToLong(mapper); - } - - /** - * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流 - * 这是一个无状态中间操作 - * - * @param mapper 操作,返回DoubleStream - * @return 返回叠加拆分操作后的DoubleStream - */ - @Override - public DoubleStream flatMapToDouble(final Function mapper) { - return stream.flatMapToDouble(mapper); - } - /** * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流,操作带一个方法,调用该方法可增加元素 * 这是一个无状态中间操作 @@ -536,17 +424,6 @@ public class EasyStream implements Stream, Iterable { }); } - /** - * 返回一个具有去重特征的流 非并行流(顺序流)下对于重复元素,保留遇到顺序中最先出现的元素,并行流情况下不能保证具体保留哪一个 - * 这是一个有状态中间操作 - * - * @return 一个具有去重特征的流 - */ - @Override - public EasyStream distinct() { - return new EasyStream<>(stream.distinct()); - } - /** * 返回一个具有去重特征的流 非并行流(顺序流)下对于重复元素,保留遇到顺序中最先出现的元素,并行流情况下不能保证具体保留哪一个 * 这是一个有状态中间操作 @@ -582,55 +459,6 @@ public class EasyStream implements Stream, Iterable { } } - /** - * 返回一个元素按自然顺序排序的流 - * 如果此流的元素不是{@code Comparable} ,则在执行终端操作时可能会抛出 {@code java.lang.ClassCastException} - * 对于顺序流,排序是稳定的。 对于无序流,没有稳定性保证。 - * 这是一个有状态中间操作 - * - * @return 一个元素按自然顺序排序的流 - */ - @Override - public EasyStream sorted() { - return new EasyStream<>(stream.sorted()); - } - - /** - * 返回一个元素按指定的{@link Comparator}排序的流 - * 如果此流的元素不是{@code Comparable} ,则在执行终端操作时可能会抛出{@code java.lang.ClassCastException} - * 对于顺序流,排序是稳定的。 对于无序流,没有稳定性保证。 - * 这是一个有状态中间操作 - * - * @param comparator 排序规则 - * @return 一个元素按指定的Comparator排序的流 - */ - @Override - public EasyStream sorted(final Comparator comparator) { - return new EasyStream<>(stream.sorted(comparator)); - } - - /** - * 返回与指定函数将元素作为参数执行后组成的流。 - * 这是一个无状态中间操作 - * - * @param action 指定的函数 - * @return 返回叠加操作后的FastStream - * @apiNote 该方法存在的意义主要是用来调试 - * 当你需要查看经过操作管道某处的元素,可以执行以下操作: - *
{@code
-	 *     .of("one", "two", "three", "four")
-	 *         .filter(e -> e.length() > 3)
-	 *         .peek(e -> System.out.println("Filtered value: " + e))
-	 *         .map(String::toUpperCase)
-	 *         .peek(e -> System.out.println("Mapped value: " + e))
-	 *         .collect(Collectors.toList());
-	 * }
- */ - @Override - public EasyStream peek(final Consumer action) { - return new EasyStream<>(stream.peek(action)); - } - /** * 返回与指定函数将元素作为参数执行后组成的流。操作带下标,并行流时下标永远为-1 * 这是一个无状态中间操作 @@ -656,6 +484,7 @@ public class EasyStream implements Stream, Iterable { return peek(e -> action.accept(e, index.incrementAndGet())); } } + /** * 返回叠加调用{@link Console#log(Object)}打印出结果的流 * @@ -665,53 +494,6 @@ public class EasyStream implements Stream, Iterable { return peek(Console::log); } - /** - * 返回截取后面一些元素的流 - * 这是一个短路状态中间操作 - * - * @param maxSize 元素截取后的个数 - * @return 截取后的流 - */ - @Override - public EasyStream limit(final long maxSize) { - return new EasyStream<>(stream.limit(maxSize)); - } - - /** - * 返回丢弃前面n个元素后的剩余元素组成的流,如果当前元素个数小于n,则返回一个元素为空的流 - * 这是一个有状态中间操作 - * - * @param n 需要丢弃的元素个数 - * @return 丢弃前面n个元素后的剩余元素组成的流 - */ - @Override - public EasyStream skip(final long n) { - return new EasyStream<>(stream.skip(n)); - } - - /** - * 返回一个串行流,该方法可以将并行流转换为串行流 - * - * @return 串行流 - */ - @Override - public EasyStream sequential() { - //noinspection ResultOfMethodCallIgnored - stream.sequential(); - return this; - } - - /** - * 对流里面的每一个元素执行一个操作 - * 这是一个终端操作 - * - * @param action 操作 - */ - @Override - public void forEach(final Consumer action) { - stream.forEach(action); - } - /** * 对流里面的每一个元素执行一个操作,操作带下标,并行流时下标永远为-1 * 这是一个终端操作 @@ -728,17 +510,6 @@ public class EasyStream implements Stream, Iterable { } } - /** - * 对流里面的每一个元素按照顺序执行一个操作 - * 这是一个终端操作 - * - * @param action 操作 - */ - @Override - public void forEachOrdered(final Consumer action) { - stream.forEachOrdered(action); - } - /** * 对流里面的每一个元素按照顺序执行一个操作,操作带下标,并行流时下标永远为-1 * 这是一个终端操作 @@ -755,216 +526,6 @@ public class EasyStream implements Stream, Iterable { } } - /** - * 返回一个包含此流元素的数组 - * 这是一个终端操作 - * - * @return 包含此流元素的数组 - */ - @Override - public Object[] toArray() { - return stream.toArray(); - } - - /** - * 返回一个包含此流元素的指定的数组,例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException} - *
{@code String[] strings = Stream.builder().add(1).build().toArray(String[]::new); }
- * - * @param generator 这里的IntFunction的参数是元素的个数,返回值为数组类型 - * @param 给定的数组类型 - * @return 包含此流元素的指定的数组 - * @throws ArrayStoreException 如果元素转换失败,例如不是该元素类型及其父类,则抛出该异常 - */ - @Override - public A[] toArray(final IntFunction generator) { - //noinspection SuspiciousToArrayCall - return stream.toArray(generator); - } - - /** - * 对元素进行聚合,并返回聚合后的值,相当于在for循环里写sum=sum+ints[i] - * 这是一个终端操作
- * 求和、最小值、最大值、平均值和转换成一个String字符串均为聚合操作 - * 例如这里对int进行求和可以写成: - * - *
{@code
-	 *     Integer sum = integers.reduce(0, (a, b) -> a+b);
-	 * }
- *

- * 或者写成: - * - *

{@code
-	 *     Integer sum = integers.reduce(0, Integer::sum);
-	 * }
- * - * @param identity 初始值,还用于限定泛型 - * @param accumulator 你想要的聚合操作 - * @return 聚合计算后的值 - */ - @Override - public T reduce(final T identity, final BinaryOperator accumulator) { - return stream.reduce(identity, accumulator); - } - - /** - * 对元素进行聚合,并返回聚合后用 {@link Optional}包裹的值,相当于在for循环里写sum=sum+ints[i] - * 该操作相当于: - *
{@code
-	 *     boolean foundAny = false;
-	 *     T result = null;
-	 *     for (T element : this stream) {
-	 *         if (!foundAny) {
-	 *             foundAny = true;
-	 *             result = element;
-	 *         }
-	 *         else
-	 *             result = accumulator.apply(result, element);
-	 *     }
-	 *     return foundAny ? Optional.of(result) : Optional.empty();
-	 * }
- * 但它不局限于顺序执行,例如并行流等情况下 - * 这是一个终端操作
- * 例如以下场景抛出 NPE : - *
{@code
-	 *      Optional reduce = Stream.builder().add(1).add(1).build().reduce((a, b) -> null);
-	 * }
- * - * @param accumulator 你想要的聚合操作 - * @return 聚合后用 {@link Optional}包裹的值 - * @throws NullPointerException 如果给定的聚合操作中执行后结果为空,并用于下一次执行,则抛出该异常 - * @see #reduce(Object, BinaryOperator) - * @see #min(Comparator) - * @see #max(Comparator) - */ - @Override - public Optional reduce(final BinaryOperator accumulator) { - return stream.reduce(accumulator); - } - - /** - * 对元素进行聚合,并返回聚合后的值,并行流时聚合拿到的初始值不稳定 - * 这是一个终端操作 - * - * @param identity 初始值 - * @param accumulator 累加器,具体为你要的聚合操作 - * @param combiner 用于并行流时组合多个结果 - * @param 初始值 - * @return 聚合操作的结果 - * @see #reduce(BinaryOperator) - * @see #reduce(Object, BinaryOperator) - */ - @Override - public U reduce(final U identity, final BiFunction accumulator, final BinaryOperator combiner) { - return stream.reduce(identity, accumulator, combiner); - } - - /** - * 对元素进行收集,并返回收集后的容器 - * 这是一个终端操作 - * - * @param supplier 提供初始值的函数式接口,一般可以传入构造参数 - * @param accumulator 具体收集操作 - * @param combiner 用于并行流时组合多个结果 - * @param 用于收集元素的容器,大多是集合 - * @return 收集后的容器 - *
{@code
-	 *  List collect = Stream.iterate(1, i -> ++i).limit(10).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
-	 * }
- */ - @Override - public R collect(final Supplier supplier, final BiConsumer accumulator, final BiConsumer combiner) { - return stream.collect(supplier, accumulator, combiner); - } - - /** - * 对元素进行收集,并返回收集后的元素 - * 这是一个终端操作 - * - * @param collector 收集器 - * @param 容器类型 - * @param
具体操作时容器类型,例如 {@code List::add} 时它为 {@code List} - * @return 收集后的容器 - */ - @Override - public R collect(final Collector collector) { - return stream.collect(collector); - } - - /** - * 获取最小值 - * - * @param comparator 一个用来比较大小的比较器{@link Comparator} - * @return 最小值 - */ - @Override - public Optional min(final Comparator comparator) { - return stream.min(comparator); - } - - /** - * 获取最大值 - * - * @param comparator 一个用来比较大小的比较器{@link Comparator} - * @return 最大值 - */ - @Override - public Optional max(final Comparator comparator) { - return stream.max(comparator); - } - - /** - * 返回流元素个数 - * - * @return 流元素个数 - */ - @Override - public long count() { - return stream.count(); - } - - /** - * 判断是否有任何一个元素满足给定断言 - * - * @param predicate 断言 - * @return 是否有任何一个元素满足给定断言 - */ - @Override - public boolean anyMatch(final Predicate predicate) { - return stream.anyMatch(predicate); - } - - /** - * 判断是否所有元素满足给定断言 - * - * @param predicate 断言 - * @return 是否所有元素满足给定断言 - */ - @Override - public boolean allMatch(final Predicate predicate) { - return stream.allMatch(predicate); - } - - /** - * 判断是否没有元素满足给定断言 - * - * @param predicate 断言 - * @return 是否没有元素满足给定断言 - */ - @Override - public boolean noneMatch(final Predicate predicate) { - return stream.noneMatch(predicate); - } - - /** - * 获取第一个元素 - * - * @return 第一个元素 - */ - @Override - public Optional findFirst() { - return stream.findFirst(); - } - /** * 获取与给定断言匹配的第一个元素 * @@ -1057,48 +618,6 @@ public class EasyStream implements Stream, Iterable { return of(array).parallel(isParallel()).onClose(stream::close); } - /** - * 考虑性能,随便取一个,这里不是随机取一个,是随便取一个 - * - * @return 随便取一个 - */ - @Override - public Optional findAny() { - return stream.findAny(); - } - - /** - * 返回流的迭代器 - * - * @return 流的迭代器 - */ - @Override - public Iterator iterator() { - return stream.iterator(); - } - - /** - * 返回流的拆分器 - * - * @return 流的拆分器 - */ - @Override - public Spliterator spliterator() { - return stream.spliterator(); - } - - /** - * 将流转换为并行 - * - * @return 并行流 - */ - @Override - public EasyStream parallel() { - //noinspection ResultOfMethodCallIgnored - stream.parallel(); - return this; - } - /** * 更改流的并行状态 * @@ -1109,30 +628,6 @@ public class EasyStream implements Stream, Iterable { return parallel ? parallel() : sequential(); } - /** - * 返回一个无序流(无手动排序) - *

标记一个流是不在意元素顺序的, 在并行流的某些情况下可以提高性能

- * - * @return 无序流 - */ - @Override - public EasyStream unordered() { - return new EasyStream<>(stream.unordered()); - } - - /** - * 在流关闭时执行操作 - * - * @param closeHandler 在流关闭时执行的操作 - * @return 流 - */ - @Override - public EasyStream onClose(final Runnable closeHandler) { - //noinspection ResultOfMethodCallIgnored - stream.onClose(closeHandler); - return this; - } - /** * 与给定元素组成的流合并,成为新的流 * @@ -1187,57 +682,14 @@ public class EasyStream implements Stream, Iterable { } /** - * 返回流的并行状态 + * 根据一个原始的流,返回一个新包装类实例 * - * @return 流的并行状态 + * @param stream 流 + * @return 实现类 */ @Override - public boolean isParallel() { - return stream.isParallel(); - } - - /** - * 关闭流 - * - * @see AutoCloseable#close() - */ - @Override - public void close() { - stream.close(); - } - - /** - * hashcode - * - * @return hashcode - */ - @Override - public int hashCode() { - return stream.hashCode(); - } - - /** - * equals - * - * @param obj 对象 - * @return 结果 - */ - @Override - public boolean equals(final Object obj) { - if (obj instanceof Stream) { - return stream.equals(obj); - } - return false; - } - - /** - * toString - * - * @return string - */ - @Override - public String toString() { - return stream.toString(); + protected EasyStream convertToStreamImpl(Stream stream) { + return new EasyStream<>(stream); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/StreamWrapper.java b/hutool-core/src/main/java/cn/hutool/core/stream/StreamWrapper.java new file mode 100644 index 000000000..60da8e88d --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/stream/StreamWrapper.java @@ -0,0 +1,563 @@ +package cn.hutool.core.stream; + +import java.util.*; +import java.util.function.*; +import java.util.stream.*; + +/** + * {@link Stream}的包装类,用于基于一个已有的流实例进行扩展 + * + * @author huangchengxing + * @see EasyStream + */ +abstract class StreamWrapper> implements Stream, Iterable { + + /** + * 原始的流实例 + */ + protected final Stream stream; + + /** + * 创建一个流包装器 + * + * @param stream 包装的流对象 + */ + protected StreamWrapper(Stream stream) { + Objects.requireNonNull(stream, "stream must not null"); + this.stream = stream; + } + + /** + * 过滤元素,返回与指定断言匹配的元素组成的流 + * 这是一个无状态中间操作 + * + * @param predicate 断言 + * @return 返回叠加过滤操作后的流 + */ + @Override + public I filter(Predicate predicate) { + return convertToStreamImpl(stream.filter(predicate)); + } + + /** + * 和{@link EasyStream#map(Function)}一样,只不过函数的返回值必须为int类型 + * 这是一个无状态中间操作 + * + * @param mapper 返回值为int类型的函数 + * @return 叠加操作后元素类型全为int的流 + */ + @Override + public IntStream mapToInt(ToIntFunction mapper) { + return stream.mapToInt(mapper); + } + + /** + * 和{@link EasyStream#map(Function)}一样,只不过函数的返回值必须为long类型 + * 这是一个无状态中间操作 + * + * @param mapper 返回值为long类型的函数 + * @return 叠加操作后元素类型全为long的流 + */ + @Override + public LongStream mapToLong(ToLongFunction mapper) { + return stream.mapToLong(mapper); + } + + /** + * 和{@link EasyStream#map(Function)}一样,只不过函数的返回值必须为double类型 + * 这是一个无状态中间操作 + * + * @param mapper 返回值为double类型的函数 + * @return 叠加操作后元素类型全为double的流 + */ + @Override + public DoubleStream mapToDouble(ToDoubleFunction mapper) { + return stream.mapToDouble(mapper); + } + + /** + * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流 + * 这是一个无状态中间操作 + * + * @param mapper 操作,返回IntStream + * @return 返回叠加拆分操作后的IntStream + */ + @Override + public IntStream flatMapToInt(Function mapper) { + return stream.flatMapToInt(mapper); + } + + /** + * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流 + * 这是一个无状态中间操作 + * + * @param mapper 操作,返回LongStream + * @return 返回叠加拆分操作后的LongStream + */ + @Override + public LongStream flatMapToLong(Function mapper) { + return stream.flatMapToLong(mapper); + } + + /** + * 扩散流操作,可能影响流元素个数,将原有流元素执行mapper操作,返回多个流所有元素组成的流 + * 这是一个无状态中间操作 + * + * @param mapper 操作,返回DoubleStream + * @return 返回叠加拆分操作后的DoubleStream + */ + @Override + public DoubleStream flatMapToDouble(Function mapper) { + return stream.flatMapToDouble(mapper); + } + + /** + * 返回一个具有去重特征的流 非并行流(顺序流)下对于重复元素,保留遇到顺序中最先出现的元素,并行流情况下不能保证具体保留哪一个 + * 这是一个有状态中间操作 + * + * @return 一个具有去重特征的流 + */ + @Override + public I distinct() { + return convertToStreamImpl(stream.distinct()); + } + + /** + * 返回一个元素按自然顺序排序的流 + * 如果此流的元素不是{@code Comparable} ,则在执行终端操作时可能会抛出 {@code java.lang.ClassCastException} + * 对于顺序流,排序是稳定的。 对于无序流,没有稳定性保证。 + * 这是一个有状态中间操作 + * + * @return 一个元素按自然顺序排序的流 + */ + @Override + public I sorted() { + return convertToStreamImpl(stream.sorted()); + } + + /** + * 返回一个元素按指定的{@link Comparator}排序的流 + * 如果此流的元素不是{@code Comparable} ,则在执行终端操作时可能会抛出{@code java.lang.ClassCastException} + * 对于顺序流,排序是稳定的。 对于无序流,没有稳定性保证。 + * 这是一个有状态中间操作 + * + * @param comparator 排序规则 + * @return 一个元素按指定的Comparator排序的流 + */ + @Override + public I sorted(Comparator comparator) { + return convertToStreamImpl(stream.sorted(comparator)); + } + + /** + * 返回与指定函数将元素作为参数执行后组成的流。 + * 这是一个无状态中间操作 + * + * @param action 指定的函数 + * @return 返回叠加操作后的FastStream + * @apiNote 该方法存在的意义主要是用来调试 + * 当你需要查看经过操作管道某处的元素,可以执行以下操作: + *
{@code
+	 *     .of("one", "two", "three", "four")
+	 *         .filter(e -> e.length() > 3)
+	 *         .peek(e -> System.out.println("Filtered value: " + e))
+	 *         .map(String::toUpperCase)
+	 *         .peek(e -> System.out.println("Mapped value: " + e))
+	 *         .collect(Collectors.toList());
+	 * }
+ */ + @Override + public I peek(Consumer action) { + return convertToStreamImpl(stream.peek(action)); + } + + /** + * 返回截取后面一些元素的流 + * 这是一个短路状态中间操作 + * + * @param maxSize 元素截取后的个数 + * @return 截取后的流 + */ + @Override + public I limit(long maxSize) { + return convertToStreamImpl(stream.limit(maxSize)); + } + + /** + * 返回丢弃前面n个元素后的剩余元素组成的流,如果当前元素个数小于n,则返回一个元素为空的流 + * 这是一个有状态中间操作 + * + * @param n 需要丢弃的元素个数 + * @return 丢弃前面n个元素后的剩余元素组成的流 + */ + @Override + public I skip(long n) { + return convertToStreamImpl(stream.skip(n)); + } + + /** + * 对流里面的每一个元素执行一个操作 + * 这是一个终端操作 + * + * @param action 操作 + */ + @Override + public void forEach(Consumer action) { + stream.forEach(action); + } + + /** + * 对流里面的每一个元素按照顺序执行一个操作 + * 这是一个终端操作 + * + * @param action 操作 + */ + @Override + public void forEachOrdered(Consumer action) { + stream.forEachOrdered(action); + } + + /** + * 返回一个包含此流元素的数组 + * 这是一个终端操作 + * + * @return 包含此流元素的数组 + */ + @Override + public Object[] toArray() { + return stream.toArray(); + } + + /** + * 返回一个包含此流元素的指定的数组,例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException} + *
{@code String[] strings = Stream.builder().add(1).build().toArray(String[]::new); }
+ * + * @param generator 这里的IntFunction的参数是元素的个数,返回值为数组类型 + * @param
给定的数组类型 + * @return 包含此流元素的指定的数组 + * @throws ArrayStoreException 如果元素转换失败,例如不是该元素类型及其父类,则抛出该异常 + */ + @Override + public A[] toArray(IntFunction generator) { + return stream.toArray(generator); + } + + /** + * 对元素进行聚合,并返回聚合后的值,相当于在for循环里写sum=sum+ints[i] + * 这是一个终端操作
+ * 求和、最小值、最大值、平均值和转换成一个String字符串均为聚合操作 + * 例如这里对int进行求和可以写成: + * + *
{@code
+	 *     Integer sum = integers.reduce(0, (a, b) -> a+b);
+	 * }
+ *

+ * 或者写成: + * + *

{@code
+	 *     Integer sum = integers.reduce(0, Integer::sum);
+	 * }
+ * + * @param identity 初始值,还用于限定泛型 + * @param accumulator 你想要的聚合操作 + * @return 聚合计算后的值 + */ + @Override + public T reduce(T identity, BinaryOperator accumulator) { + return stream.reduce(identity, accumulator); + } + + /** + * 对元素进行聚合,并返回聚合后用 {@link Optional}包裹的值,相当于在for循环里写sum=sum+ints[i] + * 该操作相当于: + *
{@code
+	 *     boolean foundAny = false;
+	 *     T result = null;
+	 *     for (T element : this stream) {
+	 *         if (!foundAny) {
+	 *             foundAny = true;
+	 *             result = element;
+	 *         }
+	 *         else
+	 *             result = accumulator.apply(result, element);
+	 *     }
+	 *     return foundAny ? Optional.of(result) : Optional.empty();
+	 * }
+ * 但它不局限于顺序执行,例如并行流等情况下 + * 这是一个终端操作
+ * 例如以下场景抛出 NPE : + *
{@code
+	 *      Optional reduce = Stream.builder().add(1).add(1).build().reduce((a, b) -> null);
+	 * }
+ * + * @param accumulator 你想要的聚合操作 + * @return 聚合后用 {@link Optional}包裹的值 + * @throws NullPointerException 如果给定的聚合操作中执行后结果为空,并用于下一次执行,则抛出该异常 + * @see #reduce(Object, BinaryOperator) + * @see #min(Comparator) + * @see #max(Comparator) + */ + @Override + public Optional reduce(BinaryOperator accumulator) { + return stream.reduce(accumulator); + } + + /** + * 对元素进行聚合,并返回聚合后的值,并行流时聚合拿到的初始值不稳定 + * 这是一个终端操作 + * + * @param identity 初始值 + * @param accumulator 累加器,具体为你要的聚合操作 + * @param combiner 用于并行流时组合多个结果 + * @param 初始值 + * @return 聚合操作的结果 + * @see #reduce(BinaryOperator) + * @see #reduce(Object, BinaryOperator) + */ + @Override + public U reduce(U identity, BiFunction accumulator, BinaryOperator combiner) { + return stream.reduce(identity, accumulator, combiner); + } + + /** + * 对元素进行收集,并返回收集后的容器 + * 这是一个终端操作 + * + * @param supplier 提供初始值的函数式接口,一般可以传入构造参数 + * @param accumulator 具体收集操作 + * @param combiner 用于并行流时组合多个结果 + * @param 用于收集元素的容器,大多是集合 + * @return 收集后的容器 + *
{@code
+	 *  List collect = Stream.iterate(1, i -> ++i).limit(10).collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
+	 * }
+ */ + @Override + public R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) { + return stream.collect(supplier, accumulator, combiner); + } + + /** + * 对元素进行收集,并返回收集后的元素 + * 这是一个终端操作 + * + * @param collector 收集器 + * @param 容器类型 + * @param
具体操作时容器类型,例如 {@code List::add} 时它为 {@code List} + * @return 收集后的容器 + */ + @Override + public R collect(Collector collector) { + return stream.collect(collector); + } + + /** + * 获取最小值 + * + * @param comparator 一个用来比较大小的比较器{@link Comparator} + * @return 最小值 + */ + @Override + public Optional min(Comparator comparator) { + return stream.min(comparator); + } + + /** + * 获取最大值 + * + * @param comparator 一个用来比较大小的比较器{@link Comparator} + * @return 最大值 + */ + @Override + public Optional max(Comparator comparator) { + return stream.max(comparator); + } + + /** + * 返回流元素个数 + * + * @return 流元素个数 + */ + @Override + public long count() { + return stream.count(); + } + + /** + * 判断是否有任何一个元素满足给定断言 + * + * @param predicate 断言 + * @return 是否有任何一个元素满足给定断言 + */ + @Override + public boolean anyMatch(Predicate predicate) { + return stream.anyMatch(predicate); + } + + /** + * 判断是否所有元素满足给定断言 + * + * @param predicate 断言 + * @return 是否所有元素满足给定断言 + */ + @Override + public boolean allMatch(Predicate predicate) { + return stream.allMatch(predicate); + } + + /** + * 判断是否没有元素满足给定断言 + * + * @param predicate 断言 + * @return 是否没有元素满足给定断言 + */ + @Override + public boolean noneMatch(Predicate predicate) { + return stream.noneMatch(predicate); + } + + /** + * 获取第一个元素 + * + * @return 第一个元素 + */ + @Override + public Optional findFirst() { + return stream.findFirst(); + } + + /** + * 考虑性能,随便取一个,这里不是随机取一个,是随便取一个 + * + * @return 随便取一个 + */ + @Override + public Optional findAny() { + return stream.findAny(); + } + + /** + * 返回流的迭代器 + * + * @return 流的迭代器 + */ + @Override + public Iterator iterator() { + return stream.iterator(); + } + + /** + * 返回流的拆分器 + * + * @return 流的拆分器 + */ + @Override + public Spliterator spliterator() { + return stream.spliterator(); + } + + /** + * 返回流的并行状态 + * + * @return 流的并行状态 + */ + @Override + public boolean isParallel() { + return stream.isParallel(); + } + + /** + * 返回一个串行流,该方法可以将并行流转换为串行流 + * + * @return 串行流 + */ + @Override + public I sequential() { + return convertToStreamImpl(stream.sequential()); + } + + /** + * 将流转换为并行 + * + * @return 并行流 + */ + @Override + public I parallel() { + return convertToStreamImpl(stream.parallel()); + } + + /** + * 返回一个无序流(无手动排序) + *

标记一个流是不在意元素顺序的, 在并行流的某些情况下可以提高性能

+ * + * @return 无序流 + */ + @Override + public I unordered() { + return convertToStreamImpl(stream.unordered()); + } + + /** + * 在流关闭时执行操作 + * + * @param closeHandler 在流关闭时执行的操作 + * @return 流 + */ + @Override + public I onClose(Runnable closeHandler) { + return convertToStreamImpl(stream.onClose(closeHandler)); + } + + /** + * 关闭流 + * + * @see AutoCloseable#close() + */ + @Override + public void close() { + stream.close(); + } + + /** + * hashcode + * + * @return hashcode + */ + @Override + public int hashCode() { + return stream.hashCode(); + } + + /** + * equals + * + * @param obj 对象 + * @return 结果 + */ + @Override + public boolean equals(final Object obj) { + if (obj instanceof Stream) { + return stream.equals(obj); + } + return false; + } + + /** + * toString + * + * @return string + */ + @Override + public String toString() { + return stream.toString(); + } + + /** + * 根据一个原始的流,返回一个新包装类实例 + * + * @param stream 流 + * @return 实现类 + */ + protected abstract I convertToStreamImpl(Stream stream); + +}