< prev index next >

src/java.base/share/classes/java/util/stream/Collectors.java

Print this page


   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
< prev index next >