From f9902311f93e6ae966fd7c5beae3428a0284c220 Mon Sep 17 00:00:00 2001
From: duandazhi 所有的jdk日期格式模式字符串 jdk18 date format pattern
+ *
+ * jdk date format pattern (Pattern Letters and Symbols) 日期格式模式字符串
+ *
+ *
+ * 常见日期格式模式字符串:
+ * 工具类,提供格式化字符串很多,但是对于具体什么含义,不够清晰,这里进行说明:
+ *
+ *
+ *
* 例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException} *
{@code String[] strings = Stream.builder().add(1).build().toArray(String[]::new); }
- *
*/
@Override
public A[] toArray(IntFunction generator) {
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java b/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java
index b5f067915c..8729ec3ec4 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/DateTimeTest.java
@@ -140,4 +140,5 @@ public class DateTimeTest {
final String a = "2021-09-27 00:00:99";
new DateTime(a, DatePattern.NORM_DATETIME_FORMAT, false);
}
+
}
From aa403cbe98cee07c7bf5637157614c3cbcff96e3 Mon Sep 17 00:00:00 2001
From: Looly 标记一个流是不在意元素顺序的, 在并行流的某些情况下可以提高性能
* * @return 无序流 */ @@ -1134,11 +1083,11 @@ public class FastStream与 jdk9 中的 takeWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
+ *本环节中是顺序执行的, 但是后续操作可以支持并行流: {@code
+ * FastStream.iterate(1, i -> i + 1)
+ * .parallel()
+ * // 顺序执行
+ * .takeWhile(e -> e < 50)
+ * // 并发
+ * .map(e -> e + 1)
+ * // 并发
+ * .map(String::valueOf)
+ * .toList();
+ * }
+ * 但是不建议在并行流中使用, 除非你确定 takeWhile 之后的操作能在并行流中受益很多
+ * + * @param predicate 断言 + * @return 与指定断言匹配的元素组成的流 + */ + public FastStreamtakeWhile 的别名方法
+ * + * @param predicate 断言 + * @return 与指定断言匹配的元素组成的流 + * @see #takeWhile(Predicate) + */ + public FastStream与 jdk9 中的 dropWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
+ *本环节中是顺序执行的, 但是后续操作可以支持并行流: {@code
+ * FastStream.iterate(1, i <= 100, i -> i + 1)
+ * .parallel()
+ * // 顺序执行
+ * .dropWhile(e -> e < 50)
+ * // 并发
+ * .map(e -> e + 1)
+ * // 并发
+ * .map(String::valueOf)
+ * .toList();
+ * }
+ * 但是不建议在并行流中使用, 除非你确定 dropWhile 之后的操作能在并行流中受益很多
+ * + * @param predicate 断言 + * @return 剩余元素组成的流 + */ + public FastStreamdropWhile 的别名方法
+ * + * @param predicate 断言 + * @return 剩余元素组成的流 + * @see #dropWhile(Predicate) + */ + public FastStream借鉴自StreamEx
+ * + * @author emptypoint + * @since 6.0.0 + */ +class DropWhileSpliterator与 jdk9 中的 takeWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
+ *本环节中是顺序执行的, 但是后续操作可以支持并行流
+ *但是不建议在并行流中使用, 除非你确定 takeWhile 之后的操作能在并行流中受益很多
+ * + * @param source 源流 + * @param与 jdk9 中的 dropWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
+ *本环节中是顺序执行的, 但是后续操作可以支持并行流
+ *但是不建议在并行流中使用, 除非你确定 dropWhile 之后的操作能在并行流中受益很多
+ * + * @param source 源流 + * @param这是一个 顺序的、有状态的流
+ *在新流的第一个节点是顺序执行的, 但是后续操作可以支持并行流
+ * + * @param source 源流 + * @param newSpliterator 新流的Spliterator + * @param借鉴自StreamEx
+ * + * @author emptypoint + * @since 6.0.0 + */ +class TakeWhileSpliterator{@code String[] strings = Stream.builder().add(1).build().toArray(String[]::new); }
+ * 例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException}
+ * {@code String[] strings = Stream.builder().add(1).build().toArray(String[]::new); }
*/
@Override
public A[] toArray(IntFunction generator) {
@@ -1423,8 +1422,8 @@ public class FastStream与 jdk9 中的 takeWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
*本环节中是顺序执行的, 但是后续操作可以支持并行流: {@code
* FastStream.iterate(1, i -> i + 1)
- * .parallel()
- * // 顺序执行
+ * .parallel()
+ * // 顺序执行
* .takeWhile(e -> e < 50)
* // 并发
* .map(e -> e + 1)
@@ -1439,7 +1438,7 @@ public class FastStream implements Stream, Iterable {
*/
public FastStream takeWhile(Predicate super T> predicate) {
Objects.requireNonNull(predicate);
- return of(StreamHelper.takeWhile(stream, predicate));
+ return of(StreamUtil.takeWhile(stream, predicate));
}
/**
@@ -1459,8 +1458,8 @@ public class FastStream implements Stream, Iterable {
* 与 jdk9 中的 dropWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
* 本环节中是顺序执行的, 但是后续操作可以支持并行流: {@code
* FastStream.iterate(1, i <= 100, i -> i + 1)
- * .parallel()
- * // 顺序执行
+ * .parallel()
+ * // 顺序执行
* .dropWhile(e -> e < 50)
* // 并发
* .map(e -> e + 1)
@@ -1475,7 +1474,7 @@ public class FastStream implements Stream, Iterable {
*/
public FastStream dropWhile(Predicate super T> predicate) {
Objects.requireNonNull(predicate);
- return of(StreamHelper.dropWhile(stream, predicate));
+ return of(StreamUtil.dropWhile(stream, predicate));
}
/**
@@ -1490,6 +1489,24 @@ public class FastStream implements Stream, Iterable {
return dropWhile(predicate);
}
+ /**
+ * 流是否为空
+ *
+ * @return 流是否为空
+ */
+ public boolean isEmpty() {
+ return !findAny().isPresent();
+ }
+
+ /**
+ * 流是否不为空
+ *
+ * @return 流是否不为空
+ */
+ public boolean isNotEmpty() {
+ return !isEmpty();
+ }
+
public interface FastStreamBuilder extends Consumer, cn.hutool.core.builder.Builder> {
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/StreamUtil.java b/hutool-core/src/main/java/cn/hutool/core/stream/StreamUtil.java
index bbd4b011a7..3cb1bd8493 100644
--- a/hutool-core/src/main/java/cn/hutool/core/stream/StreamUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/stream/StreamUtil.java
@@ -3,6 +3,9 @@ package cn.hutool.core.stream;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.lang.Assert;
+import cn.hutool.core.stream.spliterators.DropWhileSpliterator;
+import cn.hutool.core.stream.spliterators.IterateSpliterator;
+import cn.hutool.core.stream.spliterators.TakeWhileSpliterator;
import cn.hutool.core.util.CharsetUtil;
import java.io.File;
@@ -10,16 +13,20 @@ import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
+import static java.util.Objects.requireNonNull;
+
/**
* {@link Stream} 工具类
*
- * @author looly
+ * @author looly emptypoint VampireAchao
* @since 5.6.7
*/
public class StreamUtil {
@@ -141,4 +148,84 @@ public class StreamUtil {
final Function toStringFunc) {
return stream.collect(CollectorUtil.joining(delimiter, toStringFunc));
}
+
+
+ /**
+ * 返回无限有序流
+ * 该流由 初始值 然后判断条件 以及执行 迭代函数 进行迭代获取到元素
+ *
+ * @param 元素类型
+ * @param seed 初始值
+ * @param hasNext 条件值
+ * @param next 用上一个元素作为参数执行并返回一个新的元素
+ * @return 无限有序流
+ */
+ public static Stream iterate(T seed, Predicate super T> hasNext, UnaryOperator next) {
+ requireNonNull(next);
+ requireNonNull(hasNext);
+ return StreamSupport.stream(IterateSpliterator.create(seed, hasNext, next), false);
+ }
+
+ /**
+ * 保留 与指定断言 匹配时的元素, 在第一次不匹配时终止, 抛弃当前(第一个不匹配元素)及后续所有元素
+ * 与 jdk9 中的 takeWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
+ * 本环节中是顺序执行的, 但是后续操作可以支持并行流
+ * 但是不建议在并行流中使用, 除非你确定 takeWhile 之后的操作能在并行流中受益很多
+ *
+ * @param source 源流
+ * @param 元素类型
+ * @param predicate 断言
+ * @return 与指定断言匹配的元素组成的流
+ */
+ public static Stream takeWhile(Stream source, Predicate super T> predicate) {
+ requireNonNull(source);
+ requireNonNull(predicate);
+ return createStatefulNewStream(source, TakeWhileSpliterator.create(source.spliterator(), predicate));
+ }
+
+ /**
+ * 删除 与指定断言 匹配的元素, 在第一次不匹配时终止, 返回当前(第一个不匹配元素)及剩余元素组成的新流
+ * 与 jdk9 中的 dropWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作
+ * 本环节中是顺序执行的, 但是后续操作可以支持并行流
+ * 但是不建议在并行流中使用, 除非你确定 dropWhile 之后的操作能在并行流中受益很多
+ *
+ * @param source 源流
+ * @param 元素类型
+ * @param predicate 断言
+ * @return 剩余元素组成的流
+ */
+ public static Stream