From e924b77fb8ad3f4c03a199864618f7230dd49dc2 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 20 Sep 2022 09:58:05 +0800 Subject: [PATCH 1/2] =?UTF-8?q?:trollface:=20=E6=8A=BD=E5=8F=96=E5=88=B0Te?= =?UTF-8?q?rminableWrappedStream=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/stream/CollectorUtil.java | 4 +- .../cn/hutool/core/stream/EasyStream.java | 48 --- .../core/stream/TerminableWrappedStream.java | 351 ++++++++++-------- 3 files changed, 203 insertions(+), 200 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java index d318bd852..1dcc72096 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/CollectorUtil.java @@ -453,7 +453,9 @@ public class CollectorUtil { if (parentPredicate.test(e)) { parents.add(e); } - acc.add(e); + if (idGetter.apply(e) != null) { + acc.add(e); + } }, (left, right) -> { left.addAll(right); 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 1fea0642d..b892b7199 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 @@ -264,54 +264,6 @@ public class EasyStream extends AbstractEnhancedWrappedStream(stream); } - /** - *

将集合转换为树,默认用 {@code parentId == null} 来判断树的根节点 - * 因为需要在当前传入数据里查找,所以这是一个结束操作
- * - * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} - * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} - * @param childrenSetter children的setter对应的lambda,可以写作{ @code Student::setChildren} - * @param 此处是id、parentId的泛型限制 - * @return list 组装好的树
- * eg: - *

{@code
-	 * List studentTree = EasyStream.of(students).
-	 * 	toTree(Student::getId, Student::getParentId, Student::setChildren);
-	 * }
- * @author VampireAchao - */ - public > List toTree( - final Function idGetter, - final Function pIdGetter, - final BiConsumer> childrenSetter) { - return collect(CollectorUtil.toTree(idGetter, pIdGetter, childrenSetter, isParallel())); - } - - /** - * 将集合转换为树,自定义根节点的判断条件 - * 因为需要在当前传入数据里查找,所以这是一个结束操作 - * - * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} - * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} - * @param childrenSetter children的setter对应的lambda,可以写作 {@code Student::setChildren} - * @param parentPredicate 树顶部的判断条件,可以写作 {@code s -> Objects.equals(s.getParentId(),0L) } - * @param 此处是id、parentId的泛型限制 - * @return list 组装好的树
- * eg: - *
{@code
-	 * List studentTree = EasyStream.of(students).
-	 * 	.toTree(Student::getId, Student::getParentId, Student::setChildren, Student::getMatchParent);
-	 * }
- * @author VampireAchao - */ - public > List toTree( - final Function idGetter, - final Function pIdGetter, - final BiConsumer> childrenSetter, - final Predicate parentPredicate) { - return collect(CollectorUtil.toTree(idGetter, pIdGetter, childrenSetter, parentPredicate, isParallel())); - } - /** * 建造者 * diff --git a/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java b/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java index e329f9901..19958f0c4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java +++ b/hutool-core/src/main/java/cn/hutool/core/stream/TerminableWrappedStream.java @@ -22,47 +22,47 @@ import java.util.stream.Stream; */ public interface TerminableWrappedStream> extends WrappedStream { - // region ============ to collection ============ + // region ============ to collection ============ - /** - * 转换为{@link ArrayList} - * - * @return 集合 - * @see #toColl(Supplier) - */ - default List toList() { - return this.toColl(ArrayList::new); - } - - /** - * 换为不可变集合 - * - * @return 集合 + /** + * 转换为{@link ArrayList} + * + * @return 集合 * @see #toColl(Supplier) */ - default List toUnmodifiableList() { - return Collections.unmodifiableList(this.toList()); - } + default List toList() { + return this.toColl(ArrayList::new); + } - /** - * 转换为HashSet - * - * @return 集合 + /** + * 换为不可变集合 + * + * @return 集合 * @see #toColl(Supplier) */ - default Set toSet() { - return this.toColl(HashSet::new); - } + default List toUnmodifiableList() { + return Collections.unmodifiableList(this.toList()); + } - /** - * 换为不可变集合 - * - * @return 集合 + /** + * 转换为HashSet + * + * @return 集合 * @see #toColl(Supplier) */ - default Set toUnmodifiableSet() { - return Collections.unmodifiableSet(this.toSet()); - } + default Set toSet() { + return this.toColl(HashSet::new); + } + + /** + * 换为不可变集合 + * + * @return 集合 + * @see #toColl(Supplier) + */ + default Set toUnmodifiableSet() { + return Collections.unmodifiableSet(this.toSet()); + } /** * 转换成集合 @@ -76,103 +76,103 @@ public interface TerminableWrappedStream key类型 - * @return map + /** + * 转换为map,key为给定操作执行后的返回值,value为当前元素 + * + * @param keyMapper 指定的key操作 + * @param key类型 + * @return map * @see #toMap(Function, Function, BinaryOperator, Supplier) - */ - default Map toMap(final Function keyMapper) { - return this.toMap(keyMapper, Function.identity()); - } + */ + default Map toMap(final Function keyMapper) { + return this.toMap(keyMapper, Function.identity()); + } - /** - * 转换为map,key,value为给定操作执行后的返回值 - * - * @param keyMapper 指定的key操作 - * @param valueMapper 指定value操作 - * @param key类型 - * @param value类型 - * @return map + /** + * 转换为map,key,value为给定操作执行后的返回值 + * + * @param keyMapper 指定的key操作 + * @param valueMapper 指定value操作 + * @param key类型 + * @param value类型 + * @return map * @see #toMap(Function, Function, BinaryOperator, Supplier) - */ - default Map toMap( - final Function keyMapper, final Function valueMapper) { - return this.toMap(keyMapper, valueMapper, (l, r) -> r); - } + */ + default Map toMap( + final Function keyMapper, final Function valueMapper) { + return this.toMap(keyMapper, valueMapper, (l, r) -> r); + } - /** - * 转换为不可变map,key,value为给定操作执行后的返回值 - * - * @param keyMapper 指定的key操作 - * @param valueMapper 指定value操作 - * @param key类型 - * @param value类型 - * @return map + /** + * 转换为不可变map,key,value为给定操作执行后的返回值 + * + * @param keyMapper 指定的key操作 + * @param valueMapper 指定value操作 + * @param key类型 + * @param value类型 + * @return map * @see #toMap(Function, Function, BinaryOperator, Supplier) - */ - default Map toUnmodifiableMap( - final Function keyMapper, final Function valueMapper) { - return Collections.unmodifiableMap(this.toMap(keyMapper, valueMapper)); - } + */ + default Map toUnmodifiableMap( + final Function keyMapper, final Function valueMapper) { + return Collections.unmodifiableMap(this.toMap(keyMapper, valueMapper)); + } - /** - * 转换为map,key,value为给定操作执行后的返回值 - * - * @param keyMapper 指定的key操作 - * @param valueMapper 指定value操作 - * @param mergeFunction 合并操作 - * @param key类型 - * @param value类型 - * @return map + /** + * 转换为map,key,value为给定操作执行后的返回值 + * + * @param keyMapper 指定的key操作 + * @param valueMapper 指定value操作 + * @param mergeFunction 合并操作 + * @param key类型 + * @param value类型 + * @return map * @see #toMap(Function, Function, BinaryOperator, Supplier) - */ - default Map toMap( - final Function keyMapper, - final Function valueMapper, - final BinaryOperator mergeFunction) { - return this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); - } + */ + default Map toMap( + final Function keyMapper, + final Function valueMapper, + final BinaryOperator mergeFunction) { + return this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new); + } - /** - * 转换为不可变map,key,value为给定操作执行后的返回值 - * - * @param keyMapper 指定的key操作 - * @param valueMapper 指定value操作 - * @param mergeFunction 合并操作 - * @param key类型 - * @param value类型 - * @return map + /** + * 转换为不可变map,key,value为给定操作执行后的返回值 + * + * @param keyMapper 指定的key操作 + * @param valueMapper 指定value操作 + * @param mergeFunction 合并操作 + * @param key类型 + * @param value类型 + * @return map * @see #toMap(Function, Function, BinaryOperator, Supplier) - */ - default Map toUnmodifiableMap( - final Function keyMapper, - final Function valueMapper, - final BinaryOperator mergeFunction) { - return Collections.unmodifiableMap( - this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new) + */ + default Map toUnmodifiableMap( + final Function keyMapper, + final Function valueMapper, + final BinaryOperator mergeFunction) { + return Collections.unmodifiableMap( + this.toMap(keyMapper, valueMapper, mergeFunction, HashMap::new) ); - } + } - /** - * 转换为map,key,value为给定操作执行后的返回值 - * - * @param keyMapper 指定的key操作 - * @param valueMapper 指定value操作 - * @param mergeFunction 合并操作 - * @param mapSupplier map工厂 - * @param key类型 - * @param value类型 - * @param map类型 - * @return map - */ - default > M toMap( + /** + * 转换为map,key,value为给定操作执行后的返回值 + * + * @param keyMapper 指定的key操作 + * @param valueMapper 指定value操作 + * @param mergeFunction 合并操作 + * @param mapSupplier map工厂 + * @param key类型 + * @param value类型 + * @param map类型 + * @return map + */ + default > M toMap( final Function keyMapper, final Function valueMapper, final BinaryOperator mergeFunction, @@ -181,40 +181,89 @@ public interface TerminableWrappedStream将集合转换为树,默认用 {@code parentId == null} 来判断树的根节点 + * 因为需要在当前传入数据里查找,所以这是一个结束操作
+ * + * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} + * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} + * @param childrenSetter children的setter对应的lambda,可以写作{ @code Student::setChildren} + * @param 此处是id、parentId的泛型限制 + * @return list 组装好的树
+ * eg: + *
{@code
+	 * List studentTree = EasyStream.of(students).
+	 * 	toTree(Student::getId, Student::getParentId, Student::setChildren);
+	 * }
+ * @author VampireAchao + */ + default > List toTree( + final Function idGetter, + final Function pIdGetter, + final BiConsumer> childrenSetter) { + return collect(CollectorUtil.toTree(idGetter, pIdGetter, childrenSetter, isParallel())); + } - // region ============ to zip ============ + /** + * 将集合转换为树,自定义根节点的判断条件 + * 因为需要在当前传入数据里查找,所以这是一个结束操作 + * + * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} + * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} + * @param childrenSetter children的setter对应的lambda,可以写作 {@code Student::setChildren} + * @param parentPredicate 树顶部的判断条件,可以写作 {@code s -> Objects.equals(s.getParentId(),0L) } + * @param 此处是id、parentId的泛型限制 + * @return list 组装好的树
+ * eg: + *
{@code
+	 * List studentTree = EasyStream.of(students).
+	 * 	.toTree(Student::getId, Student::getParentId, Student::setChildren, Student::getMatchParent);
+	 * }
+ * @author VampireAchao + */ + default > List toTree( + final Function idGetter, + final Function pIdGetter, + final BiConsumer> childrenSetter, + final Predicate parentPredicate) { + return collect(CollectorUtil.toTree(idGetter, pIdGetter, childrenSetter, parentPredicate, isParallel())); + } - /** - * 与给定的可迭代对象转换成map,key为现有元素,value为给定可迭代对象迭代的元素
- * 至少包含全部的key,如果对应位置上的value不存在,则为null - * - * @param other 可迭代对象 - * @param 可迭代对象迭代的元素类型 - * @return map,key为现有元素,value为给定可迭代对象迭代的元素;
- * 至少包含全部的key,如果对应位置上的value不存在,则为null;
- * 如果key重复, 则保留最后一个关联的value;
- */ - default Map toZip(final Iterable other) { + + // endregion + + // region ============ to zip ============ + + /** + * 与给定的可迭代对象转换成map,key为现有元素,value为给定可迭代对象迭代的元素
+ * 至少包含全部的key,如果对应位置上的value不存在,则为null + * + * @param other 可迭代对象 + * @param 可迭代对象迭代的元素类型 + * @return map,key为现有元素,value为给定可迭代对象迭代的元素;
+ * 至少包含全部的key,如果对应位置上的value不存在,则为null;
+ * 如果key重复, 则保留最后一个关联的value;
+ */ + default Map toZip(final Iterable other) { Objects.requireNonNull(other); - // value对象迭代器 - final Iterator iterator = Opt.ofNullable(other).map(Iterable::iterator).orElseGet(Collections::emptyIterator); - if (this.isParallel()) { + // value对象迭代器 + final Iterator iterator = Opt.ofNullable(other).map(Iterable::iterator).orElseGet(Collections::emptyIterator); + if (this.isParallel()) { final List keyList = toList(); - final Map map = new HashMap<>(keyList.size()); - for (final T key : keyList) { - map.put(key, iterator.hasNext() ? iterator.next() : null); - } - return map; - } else { - return this.toMap(Function.identity(), e -> iterator.hasNext() ? iterator.next() : null); - } - } + final Map map = new HashMap<>(keyList.size()); + for (final T key : keyList) { + map.put(key, iterator.hasNext() ? iterator.next() : null); + } + return map; + } else { + return this.toMap(Function.identity(), e -> iterator.hasNext() ? iterator.next() : null); + } + } - // endregion + // endregion // region ============ to optional ============ @@ -408,7 +457,7 @@ public interface TerminableWrappedStream Map group( - final Function classifier, final Collector downstream) { + final Function classifier, final Collector downstream) { return this.group(classifier, HashMap::new, downstream); } @@ -426,9 +475,9 @@ public interface TerminableWrappedStream> M group( - final Function classifier, - final Supplier mapFactory, - final Collector downstream) { + final Function classifier, + final Supplier mapFactory, + final Collector downstream) { Objects.requireNonNull(classifier); Objects.requireNonNull(mapFactory); Objects.requireNonNull(downstream); @@ -449,8 +498,8 @@ public interface TerminableWrappedStream 值类型 - * @param predicate 判断条件 + * @param 值类型 + * @param predicate 判断条件 * @param collFactory 提供的集合 * @return map * @see #partition(Predicate, Collector) @@ -464,7 +513,7 @@ public interface TerminableWrappedStream 返回值类型 + * @param 返回值类型 * @return map */ default Map partition(final Predicate predicate, final Collector downstream) { From 463539f826903a3b164a50613c73d2307853e21f Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Tue, 20 Sep 2022 10:14:37 +0800 Subject: [PATCH 2/2] =?UTF-8?q?:trollface:=20=E8=B0=83=E6=95=B4=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../stream/AbstractEnhancedWrappedStreamTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java b/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java index 8935a75ad..be03d08bd 100644 --- a/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/stream/AbstractEnhancedWrappedStreamTest.java @@ -40,7 +40,7 @@ public class AbstractEnhancedWrappedStreamTest { @Test public void testToSet() { final List list = asList(1, 2, 3); - Set toSet = wrap(list).map(String::valueOf).toSet(); + final Set toSet = wrap(list).map(String::valueOf).toSet(); Assert.assertEquals(new HashSet<>(asList("1", "2", "3")), toSet); } @@ -636,7 +636,7 @@ public class AbstractEnhancedWrappedStreamTest { List zip = wrap(orders).zip(list, (e1, e2) -> e1 + "." + e2).toList(); Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip); - zip = wrap((Stream) EasyStream.iterate(1, i -> i + 1)).limit(10).zip(list, (e1, e2) -> e1 + "." + e2).toList(); + zip = this.wrap((Stream)EasyStream.iterate(1, i -> i + 1)).limit(10).zip(list, (e1, e2) -> e1 + "." + e2).toList(); Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip); } @@ -663,15 +663,15 @@ public class AbstractEnhancedWrappedStreamTest { } @SafeVarargs - private static Wrapper wrap(T... array) { + private final Wrapper wrap(final T... array) { return new Wrapper<>(Stream.of(array)); } - private static Wrapper wrap(Iterable iterable) { + private Wrapper wrap(final Iterable iterable) { return new Wrapper<>(StreamSupport.stream(iterable.spliterator(), false)); } - private static Wrapper wrap(Stream stream) { + private Wrapper wrap(final Stream stream) { return new Wrapper<>(stream); } @@ -683,12 +683,12 @@ public class AbstractEnhancedWrappedStreamTest { * @param stream 包装的流对象 * @throws NullPointerException 当{@code unwrap}为{@code null}时抛出 */ - protected Wrapper(Stream stream) { + protected Wrapper(final Stream stream) { super(stream); } @Override - public Wrapper wrap(Stream source) { + public Wrapper wrap(final Stream source) { return new Wrapper<>(source); }