package bjc.utils.funcutils; 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; import bjc.utils.data.IHolder; import bjc.utils.data.IPair; import bjc.utils.data.Identity; import bjc.utils.data.Pair; final class CompoundCollector implements Collector>, IPair> { private Set characteristicSet; private Collector firstCollector; private Collector secondCollector; public CompoundCollector( Collector firstCollector, Collector secondCollector) { this.firstCollector = firstCollector; this.secondCollector = secondCollector; characteristicSet = firstCollector.characteristics(); characteristicSet.addAll(secondCollector.characteristics()); } @Override public Supplier>> supplier() { return () -> new Identity<>( new Pair<>(firstCollector.supplier().get(), secondCollector.supplier().get())); } @Override public BiConsumer>, InitialType> accumulator() { BiConsumer firstAccumulator = firstCollector.accumulator(); BiConsumer secondAccumulator = secondCollector.accumulator(); return (state, value) -> { state.doWith((statePair) -> { statePair.doWith((leftState, rightState) -> { firstAccumulator.accept(leftState, value); secondAccumulator.accept(rightState, value); }); }); }; } @Override public BinaryOperator>> combiner() { BinaryOperator firstCombiner = firstCollector.combiner(); BinaryOperator secondCombiner = secondCollector.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((leftVal, rightVal) -> { return new Pair<>( firstCollector.finisher().apply(leftVal), secondCollector.finisher().apply(rightVal)); }); }); }; } @Override public Set characteristics() { return characteristicSet; } }