From 227313c632bd9138c1e7f51a79016e52fcb1cc87 Mon Sep 17 00:00:00 2001 From: huangchengxing <841396397@qq.com> Date: Mon, 22 Aug 2022 11:00:42 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=A1=A5=E5=85=85=E6=96=B9=E6=B3=95?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E4=B8=BA=E9=83=A8=E5=88=86=E5=B7=A5=E5=8E=82?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E6=B7=BB=E5=8A=A0=E7=A9=BA=E5=80=BC=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/stream/EasyStream.java | 84 +++++++++++-------- .../cn/hutool/core/stream/EasyStreamTest.java | 9 ++ 2 files changed, 58 insertions(+), 35 deletions(-) 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 212196afa..fe1bfc16e 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 @@ -1,6 +1,7 @@ package cn.hutool.core.stream; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Opt; import cn.hutool.core.lang.mutable.MutableInt; @@ -8,6 +9,7 @@ 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.*; import java.util.concurrent.ConcurrentHashMap; @@ -108,7 +110,7 @@ public class EasyStream implements Stream, Iterable { } /** - * 返回包含指定元素的串行流 + * 返回包含指定元素的串行流,若输入数组为{@code null}或空,则返回一个空的串行流 * * @param values 指定元素 * @param 元素类型 @@ -121,6 +123,40 @@ public class EasyStream implements Stream, Iterable { return ArrayUtil.isEmpty(values) ? EasyStream.empty() : new EasyStream<>(Stream.of(values)); } + /** + * 通过实现了{@link Iterable}接口的对象创建串行流,若输入对象为{@code null},则返回一个空的串行流 + * + * @param iterable 实现了{@link Iterable}接口的对象 + * @param 元素类型 + * @return 流 + */ + public static EasyStream of(Iterable iterable) { + return of(iterable, false); + } + + /** + * 通过传入的{@link Iterable}创建流,若输入对象为{@code null},则返回一个空的串行流 + * + * @param iterable {@link Iterable} + * @param parallel 是否并行 + * @param 元素类型 + * @return 流 + */ + public static EasyStream of(Iterable iterable, boolean parallel) { + return Opt.ofNullable(iterable).map(Iterable::spliterator).map(spliterator -> StreamSupport.stream(spliterator, parallel)).map(EasyStream::new).orElseGet(EasyStream::empty); + } + + /** + * 通过传入的{@link Stream}创建流,若输入对象为{@code null},则返回一个空的串行流 + * + * @param stream {@link Stream} + * @param 元素类型 + * @return 流 + */ + public static EasyStream of(Stream stream) { + return ObjUtil.isNull(stream) ? EasyStream.empty() : new EasyStream<>(stream); + } + /** * 返回无限有序流 * 该流由 初始值 以及执行 迭代函数 进行迭代获取到元素 @@ -189,40 +225,6 @@ public class EasyStream implements Stream, Iterable { return new EasyStream<>(Stream.concat(a, b)); } - /** - * 通过实现了{@link Iterable}接口的对象创建串行流 - * - * @param iterable 实现了{@link Iterable}接口的对象 - * @param 元素类型 - * @return 流 - */ - public static EasyStream of(Iterable iterable) { - return of(iterable, false); - } - - /** - * 通过传入的{@link Iterable}创建流 - * - * @param iterable {@link Iterable} - * @param parallel 是否并行 - * @param 元素类型 - * @return 流 - */ - public static EasyStream of(Iterable iterable, boolean parallel) { - return Opt.ofNullable(iterable).map(Iterable::spliterator).map(spliterator -> StreamSupport.stream(spliterator, parallel)).map(EasyStream::new).orElseGet(EasyStream::empty); - } - - /** - * 通过传入的{@link Stream}创建流 - * - * @param stream {@link Stream} - * @param 元素类型 - * @return 流 - */ - public static EasyStream of(Stream stream) { - return new EasyStream<>(Objects.requireNonNull(stream)); - } - /** * 拆分字符串,转换为串行流 * @@ -1515,6 +1517,18 @@ public class EasyStream implements Stream, Iterable { return !isEmpty(); } + /** + * 将当前流转为另一对象。用于提供针对流本身而非流中元素的操作 + * + * @param 转换类型 + * @param transform 转换 + * @return 转换后的流 + */ + public Optional transform(Function, R> transform) { + Assert.notNull(transform, "transform must not null"); + return Optional.ofNullable(transform.apply(this)); + } + public interface FastStreamBuilder extends Consumer, cn.hutool.core.builder.Builder> { /** diff --git a/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java b/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java index 51f3262e3..e989b39cd 100644 --- a/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/stream/EasyStreamTest.java @@ -427,4 +427,13 @@ public class EasyStreamTest { Assert.assertTrue(EasyStream.of(1).isNotEmpty()); } + @Test + public void testTransform() { + boolean result = EasyStream.of(1, 2, 3) + .transform(EasyStream::toList) + .map(List::isEmpty) + .orElse(false); + Assert.assertFalse(result); + } + } From 0caf36e794c78c8eadaa02eb954b9b37aa705c07 Mon Sep 17 00:00:00 2001 From: huangchengxing <841396397@qq.com> Date: Mon, 22 Aug 2022 11:01:06 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/stream/EasyStream.java | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) 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 fe1bfc16e..c6c9f14c0 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 @@ -18,32 +18,34 @@ import java.util.function.*; import java.util.stream.*; /** - * 对Stream的封装和拓展,作者经对比了vavr、eclipse-collection、stream-ex以及其他语言的api,结合日常使用习惯,进行封装和拓展 - * Stream为集合提供了一些易用api,它让开发人员能使用声明式编程的方式去编写代码 - * 它分为中间操作和结束操作 - * 中间操作分为 + *

{@link Stream}的扩展实现,基于原生Stream进行了封装和增强。
+ * 作者经对比了vavr、eclipse-collection、stream-ex以及其他语言的api,结合日常使用习惯,进行封装和拓展 + * Stream为集合提供了一些易用api,它让开发人员能使用声明式编程的方式去编写代码。 + * + *

中间操作和结束操作

+ *

针对流的操作分为分为中间操作结束操作, + * 流只有在结束操作时才会真正触发执行以往的中间操作
+ * 中间操作: *

    + *
  • 无状态中间操作: 表示不用等待 所有元素的当前操作执行完 就可以执行的操作,不依赖之前历史操作的流的状态;
  • + *
  • 有状态中间操作: 表示需要等待 所有元素的当前操作执行完 才能执行的操作,依赖之前历史操作的流的状态;
  • + *
+ * 结束操作: + *
    + *
  • 短路结束操作: 表示不用等待 所有元素的当前操作执行完 就可以执行的操作;
  • + *
  • 非短路结束操作: 表示需要等待 所有元素的当前操作执行完 才能执行的操作;
  • + *
+ * + *

串行流与并行流

+ *

流分为串行流并行流两类: + *

    + *
  • 串行流:针对流的所有操作都会通过当前线程完成;
  • *
  • - * 无状态中间操作: 表示不用等待 所有元素的当前操作执行完 就可以执行的操作,不依赖之前历史操作的流的状态 - *
  • - *
  • - * 有状态中间操作: 表示需要等待 所有元素的当前操作执行完 才能执行的操作,依赖之前历史操作的流的状态 + * 并行流:针对流的操作会通过拆分器{@link Spliterator}拆分为多个异步任务{@link java.util.concurrent.ForkJoinTask}执行, + * 这些异步任务默认使用{@link java.util.concurrent.ForkJoinPool}线程池进行管理; *
  • *
- * 结束操作分为 - *
    - *
  • - * 短路结束操作: 表示不用等待 所有元素的当前操作执行完 就可以执行的操作 - *
  • - *
  • - * 非短路结束操作: 表示需要等待 所有元素的当前操作执行完 才能执行的操作 - *
  • - *
- * 流只有在 结束操作 时才会真正触发执行以往的 中间操作 - *

- * 它分为串行流和并行流 - * 并行流会使用拆分器{@link Spliterator}将操作拆分为多个异步任务{@link java.util.concurrent.ForkJoinTask}执行 - * 这些异步任务默认使用{@link java.util.concurrent.ForkJoinPool}线程池进行管理 + * 不同类型的流可以通过{@link #sequential()}或{@link #parallel()}互相转换。 * * @author VampireAchao * @author emptypoint