分流收集器收集方式从固定Collection改为自定义收集器,可以自定义如何收集元素

This commit is contained in:
Looly 2025-04-26 13:38:45 +08:00
parent 49e9ede07b
commit 3658d9f7ca
2 changed files with 63 additions and 64 deletions

View File

@ -483,65 +483,64 @@ public class CollectorUtil {
* @author Tanglt * @author Tanglt
*/ */
public static <T, L, R> Collector<T, ?, Pair<List<L>, List<R>>> toPairList(final Function<? super T, ? extends L> lMapper, public static <T, L, R> Collector<T, ?, Pair<List<L>, List<R>>> toPairList(final Function<? super T, ? extends L> lMapper,
final Function<? super T, ? extends R> rMapper) { final Function<? super T, ? extends R> rMapper) {
return toPair(lMapper, rMapper, Collectors.toList(), Collectors.toList()); return toPair(lMapper, rMapper, Collectors.toList(), Collectors.toList());
} }
/** /**
* 将一个{@code Collection<T>}两个属性分流至两个Collection,并使用Pair收集 * 将一个{@code Collection<T>}两个属性分流至两个Collection,并使用Pair收集
* *
* @param lMapper 左属性收集方法 * @param lMapper 左属性收集方法
* @param rMapper 右属性收集方法 * @param rMapper 右属性收集方法
* @param lDownstream 左属性下游操作 * @param lDownstream 左属性下游操作
* @param rDownstream 右属性下游操作 * @param rDownstream 右属性下游操作
* @param <T> 元素类型 * @param <T> 元素类型
* @param <LU> 左属性类型 * @param <LU> 左属性类型
* @param <LA> 左属性收集类型 * @param <LA> 左属性收集类型
* @param <LR> 左属性收集最终类型 * @param <LR> 左属性收集最终类型
* @param <RU> 左属性类型 * @param <RU> 左属性类型
* @param <RA> 左属性收集类型 * @param <RA> 左属性收集类型
* @param <RR> 左属性收集最终类型 * @param <RR> 左属性收集最终类型
* @return {@code Pair<LR,RR>} Pair收集的结果 * @return {@code Pair<LR,RR>} Pair收集的结果
* @author Tanglt * @author Tanglt
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T, LU, LA, LR, RU, RA, RR> public static <T, LU, LA, LR, RU, RA, RR>
Collector<T, ?, Pair<LR, RR>> toPair(final Function<? super T, ? extends LU> lMapper, Collector<T, ?, Pair<LR, RR>> toPair(final Function<? super T, ? extends LU> lMapper,
final Function<? super T, ? extends RU> rMapper, final Function<? super T, ? extends RU> rMapper,
final Collector<? super LU, LA, LR> lDownstream, final Collector<? super LU, LA, LR> lDownstream,
final Collector<? super RU, RA, RR> rDownstream final Collector<? super RU, RA, RR> rDownstream
) { ) {
return new SimpleCollector<>( return new SimpleCollector<>(
() -> Pair.of(lDownstream.supplier().get(), rDownstream.supplier().get()), () -> Pair.of(lDownstream.supplier().get(), rDownstream.supplier().get()),
(listPair, element) -> { (listPair, element) -> {
lDownstream.accumulator().accept(listPair.getLeft(),lMapper.apply(element)); lDownstream.accumulator().accept(listPair.getLeft(), lMapper.apply(element));
rDownstream.accumulator().accept(listPair.getRight(),rMapper.apply(element)); rDownstream.accumulator().accept(listPair.getRight(), rMapper.apply(element));
}, },
(listPair1, listPair2) -> (listPair1, listPair2) ->
Pair.of(lDownstream.combiner().apply(listPair1.getLeft(),listPair2.getLeft()), Pair.of(lDownstream.combiner().apply(listPair1.getLeft(), listPair2.getLeft()),
rDownstream.combiner().apply(listPair1.getRight(),listPair2.getRight())), rDownstream.combiner().apply(listPair1.getRight(), listPair2.getRight())),
finisherPair -> { finisherPair -> {
LR finisherLeftValue; final LR finisherLeftValue;
if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
finisherLeftValue = (LR) finisherPair.getLeft(); finisherLeftValue = (LR) finisherPair.getLeft();
}else { } else {
finisherLeftValue = lDownstream.finisher().apply(finisherPair.getLeft()); finisherLeftValue = lDownstream.finisher().apply(finisherPair.getLeft());
} }
RR finisherRightValue; final RR finisherRightValue;
if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
finisherRightValue = (RR) finisherPair.getRight(); finisherRightValue = (RR) finisherPair.getRight();
}else { } else {
finisherRightValue = rDownstream.finisher().apply(finisherPair.getRight()); finisherRightValue = rDownstream.finisher().apply(finisherPair.getRight());
} }
return Pair.of(finisherLeftValue,finisherRightValue); return Pair.of(finisherLeftValue, finisherRightValue);
}, },
CH_NOID); CH_NOID);
} }
@ -562,80 +561,80 @@ public class CollectorUtil {
*/ */
public static <T, L, M, R> public static <T, L, M, R>
Collector<T, ?, Triple<List<L>, List<M>, List<R>>> toTripleList(final Function<? super T, ? extends L> lMapper, Collector<T, ?, Triple<List<L>, List<M>, List<R>>> toTripleList(final Function<? super T, ? extends L> lMapper,
final Function<? super T, ? extends M> mMapper, final Function<? super T, ? extends M> mMapper,
final Function<? super T, ? extends R> rMapper) { final Function<? super T, ? extends R> rMapper) {
return toTriple(lMapper, mMapper, rMapper, Collectors.toList(), Collectors.toList(), Collectors.toList()); return toTriple(lMapper, mMapper, rMapper, Collectors.toList(), Collectors.toList(), Collectors.toList());
} }
/** /**
* 将一个{@code Collection<T>}两个属性分流至两个Collection,并使用Pair收集 * 将一个{@code Collection<T>}两个属性分流至两个Collection,并使用Pair收集
* *
* @param lMapper 左元素收集方法 * @param lMapper 左元素收集方法
* @param mMapper 中元素收集方法 * @param mMapper 中元素收集方法
* @param rMapper 右元素收集方法 * @param rMapper 右元素收集方法
* @param lDownstream 左元素下游操作 * @param lDownstream 左元素下游操作
* @param rDownstream 右元素下游操作 * @param mDownstream 中元素下游操作
* @param <T> 元素类型 * @param rDownstream 右元素下游操作
* @param <LU> 左属性类型 * @param <T> 元素类型
* @param <LA> 左属性收集类型 * @param <LU> 左属性类型
* @param <LR> 左属性收集最终类型 * @param <LA> 左属性收集类型
* @param <MU> 中属性类型 * @param <LR> 左属性收集最终类型
* @param <MA> 中属性收集类型 * @param <MU> 中属性类型
* @param <MR> 中属性收集最终类型 * @param <MA> 中属性收集类型
* @param <RU> 左属性类型 * @param <MR> 中属性收集最终类型
* @param <RA> 左属性收集类型 * @param <RU> 左属性类型
* @param <RR> 左属性收集最终类型 * @param <RA> 左属性收集类型
* @param <RR> 左属性收集最终类型
* @return {@code Triple<LR,MR,RR>} Triple收集的结果 * @return {@code Triple<LR,MR,RR>} Triple收集的结果
* @author Tanglt * @author Tanglt
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T, LU, LA, LR, MU, MA, MR, RU, RA, RR> public static <T, LU, LA, LR, MU, MA, MR, RU, RA, RR>
Collector<T, ?, Triple<LR,MR, RR>> toTriple(final Function<? super T, ? extends LU> lMapper, Collector<T, ?, Triple<LR, MR, RR>> toTriple(final Function<? super T, ? extends LU> lMapper,
final Function<? super T, ? extends MU> mMapper, final Function<? super T, ? extends MU> mMapper,
final Function<? super T, ? extends RU> rMapper, final Function<? super T, ? extends RU> rMapper,
final Collector<? super LU, LA, LR> lDownstream, final Collector<? super LU, LA, LR> lDownstream,
final Collector<? super MU, MA, MR> mDownstream, final Collector<? super MU, MA, MR> mDownstream,
final Collector<? super RU, RA, RR> rDownstream final Collector<? super RU, RA, RR> rDownstream
) { ) {
return new SimpleCollector<>( return new SimpleCollector<>(
() -> Triple.of(lDownstream.supplier().get(), mDownstream.supplier().get(), rDownstream.supplier().get()), () -> Triple.of(lDownstream.supplier().get(), mDownstream.supplier().get(), rDownstream.supplier().get()),
(listTriple, element) -> { (listTriple, element) -> {
lDownstream.accumulator().accept(listTriple.getLeft(),lMapper.apply(element)); lDownstream.accumulator().accept(listTriple.getLeft(), lMapper.apply(element));
mDownstream.accumulator().accept(listTriple.getMiddle(),mMapper.apply(element)); mDownstream.accumulator().accept(listTriple.getMiddle(), mMapper.apply(element));
rDownstream.accumulator().accept(listTriple.getRight(),rMapper.apply(element)); rDownstream.accumulator().accept(listTriple.getRight(), rMapper.apply(element));
}, },
(listTriple1, listTriple2) -> (listTriple1, listTriple2) ->
Triple.of(lDownstream.combiner().apply(listTriple1.getLeft(),listTriple2.getLeft()), Triple.of(lDownstream.combiner().apply(listTriple1.getLeft(), listTriple2.getLeft()),
mDownstream.combiner().apply(listTriple1.getMiddle(),listTriple2.getMiddle()), mDownstream.combiner().apply(listTriple1.getMiddle(), listTriple2.getMiddle()),
rDownstream.combiner().apply(listTriple1.getRight(),listTriple2.getRight())), rDownstream.combiner().apply(listTriple1.getRight(), listTriple2.getRight())),
finisherTriple -> { finisherTriple -> {
LR finisherLeftValue; final LR finisherLeftValue;
if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
finisherLeftValue = (LR) finisherTriple.getLeft(); finisherLeftValue = (LR) finisherTriple.getLeft();
}else { } else {
finisherLeftValue = lDownstream.finisher().apply(finisherTriple.getLeft()); finisherLeftValue = lDownstream.finisher().apply(finisherTriple.getLeft());
} }
MR finisherMiddleValue; final MR finisherMiddleValue;
if (mDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { if (mDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
finisherMiddleValue = (MR) finisherTriple.getMiddle(); finisherMiddleValue = (MR) finisherTriple.getMiddle();
}else { } else {
finisherMiddleValue = mDownstream.finisher().apply(finisherTriple.getMiddle()); finisherMiddleValue = mDownstream.finisher().apply(finisherTriple.getMiddle());
} }
RR finisherRightValue; final RR finisherRightValue;
if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) { if (lDownstream.characteristics().contains(Collector.Characteristics.IDENTITY_FINISH)) {
finisherRightValue = (RR) finisherTriple.getRight(); finisherRightValue = (RR) finisherTriple.getRight();
}else { } else {
finisherRightValue = rDownstream.finisher().apply(finisherTriple.getRight()); finisherRightValue = rDownstream.finisher().apply(finisherTriple.getRight());
} }
return Triple.of(finisherLeftValue,finisherMiddleValue,finisherRightValue); return Triple.of(finisherLeftValue, finisherMiddleValue, finisherRightValue);
}, },
CH_NOID); CH_NOID);
} }

View File

@ -167,7 +167,7 @@ public class CollectorUtilTest {
Assertions.assertEquals(list.size(),tripleList.getMiddle().size()); Assertions.assertEquals(list.size(),tripleList.getMiddle().size());
Assertions.assertEquals(list.size(),tripleList.getRight().size()); Assertions.assertEquals(list.size(),tripleList.getRight().size());
Triple<Integer, List<Long>, String> tripleMixed = list.stream() final Triple<Integer, List<Long>, String> tripleMixed = list.stream()
.collect(CollectorUtil.toTriple(Triple::getLeft, Triple::getMiddle, Triple::getRight, .collect(CollectorUtil.toTriple(Triple::getLeft, Triple::getMiddle, Triple::getRight,
Collectors.summingInt(s->s), Collectors.toList(), Collectors.joining())); Collectors.summingInt(s->s), Collectors.toList(), Collectors.joining()));