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 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) -> { return new Pair<>(first.finisher().apply(left), second.finisher().apply(right)); }); }); }; } @Override public Supplier>> supplier() { return () -> { return new Identity<>(new Pair<>(first.supplier().get(), second.supplier().get())); }; } }