package bjc.utils.funcutils; import bjc.utils.data.IHolder; import bjc.utils.data.IPair; import bjc.utils.data.Identity; import bjc.utils.data.Pair; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; final class CompoundCollector implements Collector>, IPair> { private Set characteristicSet; private Collector first; private Collector second; public CompoundCollector(Collector first, Collector second) { this.first = first; this.second = second; characteristicSet = first.characteristics(); characteristicSet.addAll(second.characteristics()); } @Override public BiConsumer>, InitialType> accumulator() { BiConsumer firstAccumulator = first.accumulator(); BiConsumer secondAccumulator = second.accumulator(); return (state, value) -> { state.doWith(statePair -> { statePair.doWith((left, right) -> { firstAccumulator.accept(left, value); secondAccumulator.accept(right, value); }); }); }; } @Override public Set characteristics() { return characteristicSet; } @Override public BinaryOperator>> combiner() { BinaryOperator firstCombiner = first.combiner(); BinaryOperator secondCombiner = second.combiner(); return (leftState, rightState) -> { return leftState.unwrap(leftPair -> { return rightState.transform(rightPair -> { return leftPair.combine(rightPair, firstCombiner, secondCombiner); }); }); }; } @Override public Function>, IPair> finisher() { return state -> { return state.unwrap(pair -> { return pair.bind((left, right) -> { FinalType1 finalLeft = first.finisher().apply(left); FinalType2 finalRight = second.finisher().apply(right); return new Pair<>(finalLeft, finalRight); }); }); }; } @Override public Supplier>> supplier() { return () -> { AuxType1 initialLeft = first.supplier().get(); AuxType2 initialRight = second.supplier().get(); return new Identity<>(new Pair<>(initialLeft, initialRight)); }; } }