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..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
@@ -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;
@@ -16,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
@@ -108,7 +112,7 @@ public class EasyStream implements Stream, Iterable {
}
/**
- * 返回包含指定元素的串行流
+ * 返回包含指定元素的串行流,若输入数组为{@code null}或空,则返回一个空的串行流
*
* @param values 指定元素
* @param 元素类型
@@ -121,6 +125,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 +227,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 +1519,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);
+ }
+
}