|
Java example source code file (Collector.java)
The Collector.java Java example source code/* * Copyright (c) 2012, 2013, 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 * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.util.stream; import java.util.Collections; import java.util.EnumSet; import java.util.Objects; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; /** * A <a href="package-summary.html#Reduction">mutable reduction operation that * accumulates input elements into a mutable result container, optionally transforming * the accumulated result into a final representation after all input elements * have been processed. Reduction operations can be performed either sequentially * or in parallel. * * <p>Examples of mutable reduction operations include: * accumulating elements into a {@code Collection}; concatenating * strings using a {@code StringBuilder}; computing summary information about * elements such as sum, min, max, or average; computing "pivot table" summaries * such as "maximum valued transaction by seller", etc. The class {@link Collectors} * provides implementations of many common mutable reductions. * * <p>A {@code Collector} is specified by four functions that work together to * accumulate entries into a mutable result container, and optionally perform * a final transform on the result. They are: <ul> * <li>creation of a new result container ({@link #supplier()}) * <li>incorporating a new data element into a result container ({@link #accumulator()}) * <li>combining two result containers into one ({@link #combiner()}) * <li>performing an optional final transform on the container ({@link #finisher()}) * </ul> * * <p>Collectors also have a set of characteristics, such as * {@link Characteristics#CONCURRENT}, that provide hints that can be used by a * reduction implementation to provide better performance. * * <p>A sequential implementation of a reduction using a collector would * create a single result container using the supplier function, and invoke the * accumulator function once for each input element. A parallel implementation * would partition the input, create a result container for each partition, * accumulate the contents of each partition into a subresult for that partition, * and then use the combiner function to merge the subresults into a combined * result. * * <p>To ensure that sequential and parallel executions produce equivalent * results, the collector functions must satisfy an <em>identity and an * <a href="package-summary.html#Associativity">associativity constraints. * * <p>The identity constraint says that for any partially accumulated result, * combining it with an empty result container must produce an equivalent * result. That is, for a partially accumulated result {@code a} that is the * result of any series of accumulator and combiner invocations, {@code a} must * be equivalent to {@code combiner.apply(a, supplier.get())}. * * <p>The associativity constraint says that splitting the computation must * produce an equivalent result. That is, for any input elements {@code t1} * and {@code t2}, the results {@code r1} and {@code r2} in the computation * below must be equivalent: * <pre>{@code * A a1 = supplier.get(); * accumulator.accept(a1, t1); * accumulator.accept(a1, t2); * R r1 = finisher.apply(a1); // result without splitting * * A a2 = supplier.get(); * accumulator.accept(a2, t1); * A a3 = supplier.get(); * accumulator.accept(a3, t2); * R r2 = finisher.apply(combiner.apply(a2, a3)); // result with splitting * } </pre> * * <p>For collectors that do not have the {@code UNORDERED} characteristic, * two accumulated results {@code a1} and {@code a2} are equivalent if * {@code finisher.apply(a1).equals(finisher.apply(a2))}. For unordered * collectors, equivalence is relaxed to allow for non-equality related to * differences in order. (For example, an unordered collector that accumulated * elements to a {@code List} would consider two lists equivalent if they * contained the same elements, ignoring order.) * * <p>Libraries that implement reduction based on {@code Collector}, such as * {@link Stream#collect(Collector)}, must adhere to the following constraints: * <ul> * <li>The first argument passed to the accumulator function, both * arguments passed to the combiner function, and the argument passed to the * finisher function must be the result of a previous invocation of the * result supplier, accumulator, or combiner functions.</li> * <li>The implementation should not do anything with the result of any of * the result supplier, accumulator, or combiner functions other than to * pass them again to the accumulator, combiner, or finisher functions, * or return them to the caller of the reduction operation.</li> * <li>If a result is passed to the combiner or finisher * function, and the same object is not returned from that function, it is * never used again.</li> * <li>Once a result is passed to the combiner or finisher function, it * is never passed to the accumulator function again.</li> * <li>For non-concurrent collectors, any result returned from the result * supplier, accumulator, or combiner functions must be serially * thread-confined. This enables collection to occur in parallel without * the {@code Collector} needing to implement any additional synchronization. * The reduction implementation must manage that the input is properly * partitioned, that partitions are processed in isolation, and combining * happens only after accumulation is complete.</li> * <li>For concurrent collectors, an implementation is free to (but not * required to) implement reduction concurrently. A concurrent reduction * is one where the accumulator function is called concurrently from * multiple threads, using the same concurrently-modifiable result container, * rather than keeping the result isolated during accumulation. * A concurrent reduction should only be applied if the collector has the * {@link Characteristics#UNORDERED} characteristics or if the * originating data is unordered.</li> * </ul> * * <p>In addition to the predefined implementations in {@link Collectors}, the * static factory methods {@link #of(Supplier, BiConsumer, BinaryOperator, Characteristics...)} * can be used to construct collectors. For example, you could create a collector * that accumulates widgets into a {@code TreeSet} with: * * <pre>{@code * Collector<Widget, ?, TreeSet |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.