From a49a0139783efbe2bfcb9b5ee7c734be4cc97186 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Sun, 18 Sep 2022 18:00:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?:trollface:=20=E4=BC=98=E5=8C=96EasyStream?= =?UTF-8?q?=E4=B8=ADtoTree=E5=AF=B9predicate=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/hutool/core/stream/EasyStream.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 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 90de48122..dd60d5e13 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.lang.Opt; +import cn.hutool.core.lang.func.SerFunction; import cn.hutool.core.lang.mutable.MutableObj; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjUtil; @@ -307,17 +308,13 @@ public class EasyStream extends AbstractEnhancedWrappedStream> List toTree( - final Function idGetter, - final Function pIdGetter, - final BiConsumer> childrenSetter, - final Predicate parentPredicate) { + final Function idGetter, + final Function pIdGetter, + final BiConsumer> childrenSetter, + final SerFunction parentPredicate) { Objects.requireNonNull(parentPredicate); final List list = toList(); - final List parents = EasyStream.of(list).filter(e -> - // 此处是为了适配 parentPredicate.test空指针 情况 - // 因为Predicate.test的返回值是boolean,所以如果 e -> null 这种返回null的情况,会直接抛出NPE - Opt.ofTry(() -> parentPredicate.test(e)).filter(Boolean::booleanValue).isPresent()) - .toList(); + final List parents = EasyStream.of(list).filter(e -> Boolean.TRUE.equals(parentPredicate.apply(e))).toList(); return getChildrenFromMapByPidAndSet(idGetter, childrenSetter, EasyStream.of(list).group(pIdGetter), parents); } From c1acb2e1488cafe0bf42ee9749b27de809e7f481 Mon Sep 17 00:00:00 2001 From: VampireAchao Date: Fri, 7 Oct 2022 11:53:31 +0800 Subject: [PATCH 2/2] =?UTF-8?q?:trollface:=20=E4=BC=98=E5=8C=96EasyStream?= =?UTF-8?q?=E4=B8=ADtoTree=E5=AF=B9predicate=E7=9A=84=E5=A4=84=E7=90=86?= =?UTF-8?q?=EF=BC=8C=E8=BF=87=E6=BB=A4=E6=8E=89id=E4=B8=BAnull=E7=9A=84?= =?UTF-8?q?=E5=85=83=E7=B4=A0=EF=BC=8C=E9=81=BF=E5=85=8DStackOverflow?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/hutool/core/stream/CollectorUtil.java | 29 +++++++------------ .../core/stream/TerminableWrappedStream.java | 4 +-- .../cn/hutool/core/stream/EasyStreamTest.java | 2 ++ 3 files changed, 14 insertions(+), 21 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 29ca9f989..e5374e243 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 @@ -373,7 +373,7 @@ public class CollectorUtil { *

将集合转换为树,默认用 {@code parentId == null} 来判断树的根节点 * 因为需要在当前传入数据里查找,所以这是一个结束操作
* - * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} + * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} 会过滤掉id为null的元素 * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} * @param childrenSetter children的setter对应的lambda,可以写作{ @code Student::setChildren} * @param isParallel 是否并行去组装,数据量特别大时使用 @@ -397,7 +397,7 @@ public class CollectorUtil { *

将集合转换为树,默认用 {@code parentId == pidValue} 来判断树的根节点,可以为null * 因为需要在当前传入数据里查找,所以这是一个结束操作
* - * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} + * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} 会过滤掉id为null的元素 * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} * @param pidValue pid的值 * @param childrenSetter children的setter对应的lambda,可以写作{ @code Student::setChildren} @@ -417,7 +417,7 @@ public class CollectorUtil { final R pidValue, final BiConsumer> childrenSetter, final boolean isParallel) { - return Collectors.collectingAndThen(groupingBy(pIdGetter, Collectors.toList()), + return Collectors.collectingAndThen(filtering(e -> idGetter.apply(e) != null, groupingBy(pIdGetter, Collectors.toList())), getChildrenFromMapByPidAndSet(idGetter, pIdValuesMap -> pIdValuesMap.get(pidValue), childrenSetter, isParallel)); } @@ -425,7 +425,7 @@ public class CollectorUtil { * 将集合转换为树,自定义根节点的判断条件 * 因为需要在当前传入数据里查找,所以这是一个结束操作 * - * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} + * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} 会过滤掉id为null的元素 * @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) } @@ -447,21 +447,12 @@ public class CollectorUtil { final Predicate parentPredicate, final boolean isParallel) { final List parents = new ArrayList<>(); - return Collectors.collectingAndThen(groupingBy(pIdGetter, - new SimpleCollector<>(ArrayList::new, - (acc, e) -> { - if (parentPredicate.test(e)) { - parents.add(e); - } - if (idGetter.apply(e) != null) { - acc.add(e); - } - }, - (left, right) -> { - left.addAll(right); - return left; - }, - CH_ID)), + return Collectors.collectingAndThen(filtering(e -> { + if (parentPredicate.test(e)) { + parents.add(e); + } + return idGetter.apply(e) != null; + }, groupingBy(pIdGetter)), getChildrenFromMapByPidAndSet(idGetter, pIdValuesMap -> parents, childrenSetter, 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 19958f0c4..58f7ed10c 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 @@ -188,7 +188,7 @@ public interface TerminableWrappedStream将集合转换为树,默认用 {@code parentId == null} 来判断树的根节点 * 因为需要在当前传入数据里查找,所以这是一个结束操作
* - * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} + * @param idGetter id的getter对应的lambda,可以写作 {@code Student::getId} 会过滤掉id为null的元素 * @param pIdGetter parentId的getter对应的lambda,可以写作 {@code Student::getParentId} * @param childrenSetter children的setter对应的lambda,可以写作{ @code Student::setChildren} * @param 此处是id、parentId的泛型限制 @@ -211,7 +211,7 @@ public interface TerminableWrappedStream Objects.equals(s.getParentId(),0L) } 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 166a3f201..10d462161 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 @@ -434,6 +434,8 @@ public class EasyStreamTest { Consumer test = o -> { final List studentTree = EasyStream .of( + // 会过滤掉id为null的元素 + Student.builder().name("top").build(), Student.builder().id(1L).name("dromara").build(), Student.builder().id(2L).name("baomidou").build(), Student.builder().id(3L).name("hutool").parentId(1L).build(),