--- old/src/java.base/share/classes/java/util/stream/Collectors.java 2018-08-19 16:22:37.933008000 +0700
+++ new/src/java.base/share/classes/java/util/stream/Collectors.java 2018-08-19 16:22:37.701008000 +0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1885,6 +1885,86 @@
}
/**
+ * Returns a {@code Collector} that passes the input elements to two specified collectors
+ * and merges their results with the specified merge function.
+ *
+ *
The resulting collector is {@link Collector.Characteristics#UNORDERED} if both supplied
+ * collectors are unordered and {@link Collector.Characteristics#CONCURRENT} if both supplied
+ * collectors are concurrent.
+ *
+ * @param the type of the input elements
+ * @param the result type of the first collector
+ * @param the result type of the second collector
+ * @param the final result type
+ * @param c1 the first collector
+ * @param c2 the second collector
+ * @param merger the function which merges two results into the single one
+ * @return a {@code Collector} which aggregates the results of two supplied collectors.
+ * @since 12
+ */
+ public static
+ Collector teeingAndThen(Collector super T, ?, R1> c1,
+ Collector super T, ?, R2> c2,
+ BiFunction super R1, ? super R2, ? extends R> merger) {
+ return teeingAndThen0(c1, c2, merger);
+ }
+
+ private static
+ Collector teeingAndThen0(Collector super T, A1, R1> c1,
+ Collector super T, A2, R2> c2,
+ BiFunction super R1, ? super R2, ? extends R> merger) {
+ Objects.requireNonNull(c1, "c1");
+ Objects.requireNonNull(c2, "c2");
+ Objects.requireNonNull(merger, "merger");
+
+ Supplier c1Supplier = Objects.requireNonNull(c1.supplier(), "c1 supplier");
+ Supplier c2Supplier = Objects.requireNonNull(c2.supplier(), "c2 supplier");
+ BiConsumer c1Accumulator = Objects.requireNonNull(c1.accumulator(), "c1 accumulator");
+ BiConsumer c2Accumulator = Objects.requireNonNull(c2.accumulator(), "c2 accumulator");
+ BinaryOperator c1Combiner = Objects.requireNonNull(c1.combiner(), "c1 combiner");
+ BinaryOperator c2Combiner = Objects.requireNonNull(c2.combiner(), "c2 combiner");
+ Function c1Finisher = Objects.requireNonNull(c1.finisher(), "c1 finisher");
+ Function c2Finisher = Objects.requireNonNull(c2.finisher(), "c2 finisher");
+
+ Set characteristics;
+ Set c1Characteristics = c1.characteristics();
+ Set c2Characteristics = c2.characteristics();
+ if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
+ characteristics = CH_NOID;
+ } else {
+ EnumSet c = EnumSet.noneOf(Collector.Characteristics.class);
+ c.addAll(c1Characteristics);
+ c.retainAll(c2Characteristics);
+ c.remove(Collector.Characteristics.IDENTITY_FINISH);
+ characteristics = Collections.unmodifiableSet(c);
+ }
+
+ class PairBox {
+ A1 left = c1Supplier.get();
+ A2 right = c2Supplier.get();
+
+ void add(T t) {
+ c1Accumulator.accept(left, t);
+ c2Accumulator.accept(right, t);
+ }
+
+ PairBox combine(PairBox other) {
+ left = c1Combiner.apply(left, other.left);
+ right = c2Combiner.apply(right, other.right);
+ return this;
+ }
+
+ R get() {
+ R1 r1 = c1Finisher.apply(left);
+ R2 r2 = c2Finisher.apply(right);
+ return merger.apply(r1, r2);
+ }
+ }
+
+ return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);
+ }
+
+ /**
* Implementation class used by partitioningBy.
*/
private static final class Partition