1 /*
2 * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1865 }
1866
1867 /**
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
|
1 /*
2 * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
1865 }
1866
1867 /**
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 is a composite of two downstream collectors.
1889 * Every element passed to the resulting collector is processed by both downstream
1890 * collectors, then their results are merged using the specified merge function
1891 * into the final result.
1892 *
1893 * <p>The resulting collector functions do the following:
1894 *
1895 * <ul>
1896 * <li>supplier: creates a result container that contains result containers
1897 * obtained by calling each collector's supplier
1898 * <li>accumulator: calls each collector's accumulator with its result container
1899 * and the input element
1900 * <li>combiner: calls each collector's combiner with two result containers
1901 * <li>finisher: calls each collector's finisher with its result container,
1902 * then calls the supplied merger and returns its result.
1903 * </ul>
1904 *
1905 * <p>The resulting collector is {@link Collector.Characteristics#UNORDERED} if both downstream
1906 * collectors are unordered and {@link Collector.Characteristics#CONCURRENT} if both downstream
1907 * collectors are concurrent.
1908 *
1909 * @param <T> the type of the input elements
1910 * @param <R1> the result type of the first collector
1911 * @param <R2> the result type of the second collector
1912 * @param <R> the final result type
1913 * @param downstream1 the first downstream collector
1914 * @param downstream2 the second downstream collector
1915 * @param merger the function which merges two results into the single one
1916 * @return a {@code Collector} which aggregates the results of two supplied collectors.
1917 * @since 12
1918 */
1919 public static <T, R1, R2, R>
1920 Collector<T, ?, R> teeing(Collector<? super T, ?, R1> downstream1,
1921 Collector<? super T, ?, R2> downstream2,
1922 BiFunction<? super R1, ? super R2, R> merger) {
1923 return teeing0(downstream1, downstream2, merger);
1924 }
1925
1926 private static <T, A1, A2, R1, R2, R>
1927 Collector<T, ?, R> teeing0(Collector<? super T, A1, R1> downstream1,
1928 Collector<? super T, A2, R2> downstream2,
1929 BiFunction<? super R1, ? super R2, R> merger) {
1930 Objects.requireNonNull(downstream1, "downstream1");
1931 Objects.requireNonNull(downstream2, "downstream2");
1932 Objects.requireNonNull(merger, "merger");
1933
1934 Supplier<A1> c1Supplier = Objects.requireNonNull(downstream1.supplier(), "downstream1 supplier");
1935 Supplier<A2> c2Supplier = Objects.requireNonNull(downstream2.supplier(), "downstream2 supplier");
1936 BiConsumer<A1, ? super T> c1Accumulator =
1937 Objects.requireNonNull(downstream1.accumulator(), "downstream1 accumulator");
1938 BiConsumer<A2, ? super T> c2Accumulator =
1939 Objects.requireNonNull(downstream2.accumulator(), "downstream2 accumulator");
1940 BinaryOperator<A1> c1Combiner = Objects.requireNonNull(downstream1.combiner(), "downstream1 combiner");
1941 BinaryOperator<A2> c2Combiner = Objects.requireNonNull(downstream2.combiner(), "downstream2 combiner");
1942 Function<A1, R1> c1Finisher = Objects.requireNonNull(downstream1.finisher(), "downstream1 finisher");
1943 Function<A2, R2> c2Finisher = Objects.requireNonNull(downstream2.finisher(), "downstream2 finisher");
1944
1945 Set<Collector.Characteristics> characteristics;
1946 Set<Collector.Characteristics> c1Characteristics = downstream1.characteristics();
1947 Set<Collector.Characteristics> c2Characteristics = downstream2.characteristics();
1948 if (CH_ID.containsAll(c1Characteristics) || CH_ID.containsAll(c2Characteristics)) {
1949 characteristics = CH_NOID;
1950 } else {
1951 EnumSet<Collector.Characteristics> c = EnumSet.noneOf(Collector.Characteristics.class);
1952 c.addAll(c1Characteristics);
1953 c.retainAll(c2Characteristics);
1954 c.remove(Collector.Characteristics.IDENTITY_FINISH);
1955 characteristics = Collections.unmodifiableSet(c);
1956 }
1957
1958 class PairBox {
1959 A1 left = c1Supplier.get();
1960 A2 right = c2Supplier.get();
1961
1962 void add(T t) {
1963 c1Accumulator.accept(left, t);
1964 c2Accumulator.accept(right, t);
1965 }
1966
1967 PairBox combine(PairBox other) {
1968 left = c1Combiner.apply(left, other.left);
1969 right = c2Combiner.apply(right, other.right);
1970 return this;
1971 }
1972
1973 R get() {
1974 R1 r1 = c1Finisher.apply(left);
1975 R2 r2 = c2Finisher.apply(right);
1976 return merger.apply(r1, r2);
1977 }
1978 }
1979
1980 return new CollectorImpl<>(PairBox::new, PairBox::add, PairBox::combine, PairBox::get, characteristics);
1981 }
1982
1983 /**
1984 * Implementation class used by partitioningBy.
1985 */
1986 private static final class Partition<T>
1987 extends AbstractMap<Boolean, T>
1988 implements Map<Boolean, T> {
1989 final T forTrue;
1990 final T forFalse;
1991
1992 Partition(T forTrue, T forFalse) {
1993 this.forTrue = forTrue;
1994 this.forFalse = forFalse;
1995 }
1996
1997 @Override
1998 public Set<Map.Entry<Boolean, T>> entrySet() {
1999 return new AbstractSet<>() {
2000 @Override
|