1868 * Returns a {@code Collector} which applies an {@code double}-producing
1869 * mapping function to each input element, and returns summary statistics
1870 * for the resulting values.
1871 *
1872 * @param <T> the type of the input elements
1873 * @param mapper a mapping function to apply to each element
1874 * @return a {@code Collector} implementing the summary-statistics reduction
1875 *
1876 * @see #summarizingLong(ToLongFunction)
1877 * @see #summarizingInt(ToIntFunction)
1878 */
1879 public static <T>
1880 Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
1881 return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>(
1882 DoubleSummaryStatistics::new,
1883 (r, t) -> r.accept(mapper.applyAsDouble(t)),
1884 (l, r) -> { l.combine(r); return l; }, CH_ID);
1885 }
1886
1887 /**
1888 * Implementation class used by partitioningBy.
1889 */
1890 private static final class Partition<T>
1891 extends AbstractMap<Boolean, T>
1892 implements Map<Boolean, T> {
1893 final T forTrue;
1894 final T forFalse;
1895
1896 Partition(T forTrue, T forFalse) {
1897 this.forTrue = forTrue;
1898 this.forFalse = forFalse;
1899 }
1900
1901 @Override
1902 public Set<Map.Entry<Boolean, T>> entrySet() {
1903 return new AbstractSet<>() {
1904 @Override
1905 public Iterator<Map.Entry<Boolean, T>> iterator() {
1906 Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse);
1907 Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue);
|
1868 * Returns a {@code Collector} which applies an {@code double}-producing
1869 * mapping function to each input element, and returns summary statistics
1870 * for the resulting values.
1871 *
1872 * @param <T> the type of the input elements
1873 * @param mapper a mapping function to apply to each element
1874 * @return a {@code Collector} implementing the summary-statistics reduction
1875 *
1876 * @see #summarizingLong(ToLongFunction)
1877 * @see #summarizingInt(ToIntFunction)
1878 */
1879 public static <T>
1880 Collector<T, ?, DoubleSummaryStatistics> summarizingDouble(ToDoubleFunction<? super T> mapper) {
1881 return new CollectorImpl<T, DoubleSummaryStatistics, DoubleSummaryStatistics>(
1882 DoubleSummaryStatistics::new,
1883 (r, t) -> r.accept(mapper.applyAsDouble(t)),
1884 (l, r) -> { l.combine(r); return l; }, CH_ID);
1885 }
1886
1887 /**
1888 * Returns a {@code Collector} that passes the input elements to two specified collectors
1889 * and merges their results with the specified merge function.
1890 *
1891 * <p>The resulting collector is {@link Collector.Characteristics#UNORDERED} if both supplied
1892 * collectors are unordered and {@link Collector.Characteristics#CONCURRENT} if both supplied
1893 * collectors are concurrent.
1894 *
1895 * @param <T> the type of the input elements
1896 * @param <R1> the result type of the first collector
1897 * @param <R2> the result type of the second collector
1898 * @param <R> the final result type
1899 * @param c1 the first collector
1900 * @param c2 the second collector
1901 * @param finisher the function which merges two results into the single one
1902 * @return a {@code Collector} which aggregates the results of two supplied collectors.
1903 * @since 11
1904 */
1905 public static <T, R1, R2, R>
1906 Collector<T, ?, R> pairing(Collector<? super T, ?, R1> c1,
1907 Collector<? super T, ?, R2> c2,
1908 BiFunction<? super R1, ? super R2, ? extends R> finisher) {
1909 return pairing0(c1, c2, finisher);
1910 }
1911
1912 private static <T, A1, A2, R1, R2, R>
1913 Collector<T, ?, R> pairing0(Collector<? super T, A1, R1> c1,
1914 Collector<? super T, A2, R2> c2,
1915 BiFunction<? super R1, ? super R2, ? extends R> finisher) {
1916 Objects.requireNonNull(c1, "c1");
1917 Objects.requireNonNull(c2, "c2");
1918 Objects.requireNonNull(finisher, "finisher");
1919 EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1920 c.addAll(c1.characteristics());
1921 c.retainAll(c2.characteristics());
1922 c.remove(Collector.Characteristics.IDENTITY_FINISH);
1923
1924 Supplier<A1> c1Supplier = Objects.requireNonNull(c1.supplier(), "c1 supplier");
1925 Supplier<A2> c2Supplier = Objects.requireNonNull(c2.supplier(), "c2 supplier");
1926 BiConsumer<A1, ? super T> c1Accumulator = Objects.requireNonNull(c1.accumulator(), "c1 accumulator");
1927 BiConsumer<A2, ? super T> c2Accumulator = Objects.requireNonNull(c2.accumulator(), "c2 accumulator");
1928 BinaryOperator<A1> c1Combiner = Objects.requireNonNull(c1.combiner(), "c1 combiner");
1929 BinaryOperator<A2> c2Combiner = Objects.requireNonNull(c2.combiner(), "c2 combiner");
1930 Function<A1, R1> c1Finisher = Objects.requireNonNull(c1.finisher(), "c1 finisher");
1931 Function<A2, R2> c2Finisher = Objects.requireNonNull(c2.finisher(), "c2 finisher");
1932
1933 class PairBox {
1934 A1 left = c1Supplier.get();
1935 A2 right = c2Supplier.get();
1936
1937 void add(T t) {
1938 c1Accumulator.accept(left, t);
1939 c2Accumulator.accept(right, t);
1940 }
1941
1942 PairBox combine(PairBox other) {
1943 left = c1Combiner.apply(left, other.left);
1944 right = c2Combiner.apply(right, other.right);
1945 return this;
1946 }
1947
1948 R get() {
1949 R1 r1 = c1Finisher.apply(left);
1950 R2 r2 = c2Finisher.apply(right);
1951 return finisher.apply(r1, r2);
1952 }
1953 }
1954
1955 return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get,
1956 Collections.unmodifiableSet(c));
1957 }
1958
1959 /**
1960 * Implementation class used by partitioningBy.
1961 */
1962 private static final class Partition<T>
1963 extends AbstractMap<Boolean, T>
1964 implements Map<Boolean, T> {
1965 final T forTrue;
1966 final T forFalse;
1967
1968 Partition(T forTrue, T forFalse) {
1969 this.forTrue = forTrue;
1970 this.forFalse = forFalse;
1971 }
1972
1973 @Override
1974 public Set<Map.Entry<Boolean, T>> entrySet() {
1975 return new AbstractSet<>() {
1976 @Override
1977 public Iterator<Map.Entry<Boolean, T>> iterator() {
1978 Map.Entry<Boolean, T> falseEntry = new SimpleImmutableEntry<>(false, forFalse);
1979 Map.Entry<Boolean, T> trueEntry = new SimpleImmutableEntry<>(true, forTrue);
|