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.- * */ @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 b5f067915..8729ec3ec 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: Loolybuilder().add(1).build().toArray(String[]::new); }
标记一个流是不在意元素顺序的, 在并行流的某些情况下可以提高性能
* * @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.+ * 例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException} + *builder().add(1).build().toArray(String[]::new); }
{@code String[] strings = Stream.*/ @Override public A[] toArray(IntFunction generator) { @@ -1423,8 +1422,8 @@ public class FastStreambuilder().add(1).build().toArray(String[]::new); }
与 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 FastStreamimplements 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 FastStreamimplements 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 bbd4b011a..3cb1bd849 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