diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java index 8be5e957b..4c62590d2 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/stream/CollectorUtil.java @@ -17,6 +17,8 @@ package org.dromara.hutool.core.stream; import org.dromara.hutool.core.array.ArrayUtil; +import org.dromara.hutool.core.lang.tuple.Pair; +import org.dromara.hutool.core.lang.tuple.Triple; import org.dromara.hutool.core.text.StrUtil; import java.util.*; @@ -468,4 +470,134 @@ public class CollectorUtil { downstream.combiner(), downstream.finisher(), downstream.characteristics()); } + + /** + * 将一个Collection两个属性分流至两个ArrayList,并使用Pair收集。 + * + * @param lMapper 左属性收集方法 + * @param rMapper 右属性收集方法 + * @param 元素类型 + * @param 左属性类型 + * @param 右属性类型 + * @return Pair,List> Pair收集的两个List + * @author Tanglt + */ + public static Collector,List>, Pair,List>> toPairList(Function lMapper, + Function rMapper) { + return toPairCollection(lMapper,rMapper,ArrayList::new,ArrayList::new); + + } + + /** + * 将一个Collection两个属性分流至两个Collection,并使用Pair收集。需要指定Collection类型 + * + * @param lMapper 左属性收集方法 + * @param rMapper 右属性收集方法 + * @param newCollectionL 左属性Collection创建方法 + * @param newCollectionR 右属性Collection创建方法 + * @param 元素类型 + * @param 左属性类型 + * @param 右属性类型 + * @param 左分流Collection类型 + * @param 右分流Collection类型 + * @return Pair,C> Pair收集的两个List + * @author Tanglt + */ + public static ,RC extends Collection> + Collector, Pair> toPairCollection(Function lMapper, + Function rMapper, + Supplier newCollectionL, + Supplier newCollectionR) { + return new SimpleCollector<>(() -> Pair.of(newCollectionL.get(), newCollectionR.get()), + (listPair, element) -> { + L lValue = lMapper.apply(element); + if (lValue != null) { + listPair.getLeft().add(lValue); + } + R rValue = rMapper.apply(element); + if (rValue != null) { + listPair.getRight().add(rValue); + } + }, + (listPair1, listPair2) -> { + listPair1.getLeft().addAll(listPair2.getLeft()); + listPair1.getRight().addAll(listPair2.getRight()); + return listPair1; + }, + CH_ID); + } + + /** + * 将一个Collection三个属性分流至三个ArrayList,并使用Triple收集。 + * + * @param lMapper 左属性收集方法 + * @param mMapper 中属性收集方法 + * @param rMapper 右属性收集方法 + * @param 元素类型 + * @param 左属性类型 + * @param 中属性类型 + * @param 右属性类型 + * @return Triple,List,List> Triple收集的三个List + * @author Tanglt + */ + public static + Collector, List, List>, Triple, List, List>> toTripleList(Function lMapper, + Function mMapper, + Function rMapper) { + return toTripleCollection(lMapper, mMapper, rMapper, ArrayList::new, ArrayList::new, ArrayList::new); + } + + /** + * 将一个Collection两个属性分流至两个Collection,并使用Pair收集。需要指定Collection类型 + * + * @param lMapper 左属性收集方法 + * @param mMapper 中属性收集方法 + * @param rMapper 右属性收集方法 + * @param newCollectionL 左属性Collection创建方法 + * @param newCollectionM 中属性Collection创建方法 + * @param newCollectionR 右属性Collection创建方法 + * @param 元素类型 + * @param 左属性类型 + * @param 中属性类型 + * @param 右属性类型 + * @param 左分流Collection类型 + * @param 中分流Collection类型 + * @param 右分流Collection类型 + * @return Triple,MC,RC> Triple收集的三个List + * @author Tanglt + */ + public static , + MC extends Collection, + RC extends Collection> + Collector,Triple> toTripleCollection(Function lMapper, + Function mMapper, + Function rMapper, + Supplier newCollectionL, + Supplier newCollectionM, + Supplier newCollectionR){ + return new SimpleCollector<>( + () -> Triple.of(newCollectionL.get(),newCollectionM.get(), newCollectionR.get()), + (listTriple, element) -> { + L lValue = lMapper.apply(element); + if (lValue != null) { + listTriple.getLeft().add(lValue); + } + M mValue = mMapper.apply(element); + if (mValue != null) { + listTriple.getMiddle().add(mValue); + } + R rValue = rMapper.apply(element); + if (rValue != null) { + listTriple.getRight().add(rValue); + } + }, + (listTriple1, listTriple2) -> { + listTriple1.getLeft().addAll(listTriple2.getLeft()); + listTriple1.getRight().addAll(listTriple2.getRight()); + return listTriple1; + }, + CH_ID); + } + } diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java index 27a115abe..4eab5d0d8 100644 --- a/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java +++ b/hutool-core/src/test/java/org/dromara/hutool/core/stream/CollectorUtilTest.java @@ -17,6 +17,8 @@ package org.dromara.hutool.core.stream; import org.dromara.hutool.core.collection.ListUtil; +import org.dromara.hutool.core.lang.tuple.Pair; +import org.dromara.hutool.core.lang.tuple.Triple; import org.dromara.hutool.core.map.MapUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -135,4 +137,43 @@ public class CollectorUtilTest { } + + @Test + public void testToPairList() { + final List> list = Arrays.asList(Pair.of(1,"one"), Pair.of(2,"two")); + Pair, List> pairList = list.stream() + .collect(CollectorUtil.toPairList(Pair::getLeft, Pair::getRight)); + + Assertions.assertEquals(pairList.getLeft().size(),list.size()); + Assertions.assertEquals(pairList.getRight().size(),list.size()); + + Pair, ArrayList> pairMixed = list.stream() + .collect(CollectorUtil.toPairCollection(Pair::getLeft, Pair::getRight, HashSet::new, ArrayList::new)); + + Assertions.assertEquals(pairMixed.getLeft().size(),list.size()); + Assertions.assertEquals(pairMixed.getRight().size(),list.size()); + + } + + + @Test + public void testToTripleList() { + final List> list + = Arrays.asList(Triple.of(1,1L,"one"), Triple.of(2,2L,"two")); + Triple, List, List> tripleList = list.stream() + .collect(CollectorUtil.toTripleList(Triple::getLeft, Triple::getMiddle, Triple::getRight)); + + Assertions.assertEquals(tripleList.getLeft().size(),list.size()); + Assertions.assertEquals(tripleList.getMiddle().size(),list.size()); + Assertions.assertEquals(tripleList.getRight().size(),list.size()); + + Triple, HashSet, ArrayList> tripleMixed = list.stream() + .collect(CollectorUtil.toTripleCollection(Triple::getLeft, Triple::getMiddle, Triple::getRight, HashSet::new, HashSet::new, ArrayList::new)); + + Assertions.assertEquals(tripleMixed.getLeft().size(),list.size()); + Assertions.assertEquals(tripleMixed.getMiddle().size(),list.size()); + Assertions.assertEquals(tripleMixed.getRight().size(),list.size()); + + } + }