jdk/src/share/classes/java/util/stream/Collector.java
author briangoetz
Wed, 17 Apr 2013 14:39:04 -0400
changeset 17167 87067e3340d3
child 19214 e5901820c3c1
permissions -rw-r--r--
8008682: Inital Streams public API Reviewed-by: mduigou, dholmes, darcy Contributed-by: Brian Goetz <brian.goetz@oracle.com>, Mike Duigou <mike.duigou@oracle.com>, Paul Sandoz <paul.sandoz@oracle.com>, JSR-335 EG <lambda-libs-spec-experts@openjdk.java.net>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
17167
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     1
/*
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     2
 * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     4
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    10
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    15
 * accompanied this code).
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    16
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    20
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    23
 * questions.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    24
 */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    25
package java.util.stream;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    26
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    27
import java.util.Collections;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    28
import java.util.Set;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    29
import java.util.function.BiFunction;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    30
import java.util.function.BinaryOperator;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    31
import java.util.function.Supplier;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    32
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    33
/**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    34
 * A <a href="package-summary.html#Reduction">reduction operation</a> that
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    35
 * supports folding input elements into a cumulative result.  The result may be
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    36
 * a value or may be a mutable result container.  Examples of operations
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    37
 * accumulating results into a mutable result container include: accumulating
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    38
 * input elements into a {@code Collection}; concatenating strings into a
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    39
 * {@code StringBuilder}; computing summary information about elements such as
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    40
 * sum, min, max, or average; computing "pivot table" summaries such as "maximum
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    41
 * valued transaction by seller", etc.  Reduction operations can be performed
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    42
 * either sequentially or in parallel.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    43
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    44
 * <p>The following are examples of using the predefined {@code Collector}
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    45
 * implementations in {@link Collectors} with the {@code Stream} API to perform
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    46
 * mutable reduction tasks:
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    47
 * <pre>{@code
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    48
 *     // Accumulate elements into a List
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    49
 *     List<String> list = stream.collect(Collectors.toList());
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    50
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    51
 *     // Accumulate elements into a TreeSet
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    52
 *     Set<String> list = stream.collect(Collectors.toCollection(TreeSet::new));
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    53
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    54
 *     // Convert elements to strings and concatenate them, separated by commas
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    55
 *     String joined = stream.map(Object::toString)
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    56
 *                           .collect(Collectors.toStringJoiner(", "))
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    57
 *                           .toString();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    58
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    59
 *     // Find highest-paid employee
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    60
 *     Employee highestPaid = employees.stream()
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    61
 *                                     .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    62
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    63
 *     // Group employees by department
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    64
 *     Map<Department, List<Employee>> byDept
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    65
 *         = employees.stream()
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    66
 *                    .collect(Collectors.groupingBy(Employee::getDepartment));
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    67
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    68
 *     // Find highest-paid employee by department
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    69
 *     Map<Department, Employee> highestPaidByDept
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    70
 *         = employees.stream()
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    71
 *                    .collect(Collectors.groupingBy(Employee::getDepartment,
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    72
 *                                                   Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    73
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    74
 *     // Partition students into passing and failing
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    75
 *     Map<Boolean, List<Student>> passingFailing =
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    76
 *         students.stream()
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    77
 *                 .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    78
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    79
 * }</pre>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    80
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    81
 * <p>A {@code Collector} is specified by three functions that work together to
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    82
 * manage a result or result container.  They are: creation of an initial
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    83
 * result, incorporating a new data element into a result, and combining two
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    84
 * results into one. The last function -- combining two results into one -- is
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    85
 * used during parallel operations, where subsets of the input are accumulated
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    86
 * in parallel, and then the subresults merged into a combined result. The
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    87
 * result may be a mutable container or a value.  If the result is mutable, the
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    88
 * accumulation and combination functions may either mutate their left argument
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    89
 * and return that (such as adding elements to a collection), or return a new
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    90
 * result, in which case it should not perform any mutation.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    91
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    92
 * <p>Collectors also have a set of characteristics, including
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    93
 * {@link Characteristics#CONCURRENT} and
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    94
 * {@link Characteristics#STRICTLY_MUTATIVE}.  These characteristics provide
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    95
 * hints that can be used by a reduction implementation to provide better
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    96
 * performance.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    97
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    98
 * <p>Libraries that implement reduction based on {@code Collector}, such as
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
    99
 * {@link Stream#collect(Collector)}, must adhere to the following constraints:
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   100
 * <ul>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   101
 *     <li>The first argument passed to the accumulator function, and both
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   102
 *     arguments passed to the combiner function, must be the result of a
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   103
 *     previous invocation of {@link #resultSupplier()}, {@link #accumulator()},
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   104
 *     or {@link #combiner()}.</li>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   105
 *     <li>The implementation should not do anything with the result of any of
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   106
 *     the result supplier, accumulator, or combiner functions other than to
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   107
 *     pass them again to the accumulator or combiner functions, or return them
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   108
 *     to the caller of the reduction operation.</li>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   109
 *     <li>If a result is passed to the accumulator or combiner function, and
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   110
 *     the same object is not returned from that function, it is never used
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   111
 *     again.</li>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   112
 *     <li>Once a result is passed to the combiner function, it is never passed
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   113
 *     to the accumulator function again.</li>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   114
 *     <li>For non-concurrent collectors, any result returned from the result
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   115
 *     supplier, accumulator, or combiner functions must be serially
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   116
 *     thread-confined.  This enables collection to occur in parallel without
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   117
 *     the {@code Collector} needing to implement any additional synchronization.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   118
 *     The reduction implementation must manage that the input is properly
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   119
 *     partitioned, that partitions are processed in isolation, and combining
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   120
 *     happens only after accumulation is complete.</li>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   121
 *     <li>For concurrent collectors, an implementation is free to (but not
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   122
 *     required to) implement reduction concurrently.  A concurrent reduction
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   123
 *     is one where the accumulator function is called concurrently from
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   124
 *     multiple threads, using the same concurrently-modifiable result container,
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   125
 *     rather than keeping the result isolated during accumulation.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   126
 *     A concurrent reduction should only be applied if the collector has the
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   127
 *     {@link Characteristics#UNORDERED} characteristics or if the
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   128
 *     originating data is unordered.</li>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   129
 * </ul>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   130
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   131
 * @apiNote
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   132
 * Performing a reduction operation with a {@code Collector} should produce a
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   133
 * result equivalent to:
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   134
 * <pre>{@code
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   135
 *     BiFunction<R,T,R> accumulator = collector.accumulator();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   136
 *     R result = collector.resultSupplier().get();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   137
 *     for (T t : data)
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   138
 *         result = accumulator.apply(result, t);
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   139
 *     return result;
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   140
 * }</pre>
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   141
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   142
 * <p>However, the library is free to partition the input, perform the reduction
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   143
 * on the partitions, and then use the combiner function to combine the partial
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   144
 * results to achieve a parallel reduction.  Depending on the specific reduction
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   145
 * operation, this may perform better or worse, depending on the relative cost
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   146
 * of the accumulator and combiner functions.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   147
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   148
 * <p>An example of an operation that can be easily modeled by {@code Collector}
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   149
 * is accumulating elements into a {@code TreeSet}. In this case, the {@code
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   150
 * resultSupplier()} function is {@code () -> new Treeset<T>()}, the
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   151
 * {@code accumulator} function is
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   152
 * {@code (set, element) -> { set.add(element); return set; }}, and the combiner
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   153
 * function is {@code (left, right) -> { left.addAll(right); return left; }}.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   154
 * (This behavior is implemented by
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   155
 * {@code Collectors.toCollection(TreeSet::new)}).
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   156
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   157
 * TODO Associativity and commutativity
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   158
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   159
 * @see Stream#collect(Collector)
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   160
 * @see Collectors
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   161
 *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   162
 * @param <T> the type of input element to the collect operation
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   163
 * @param <R> the result type of the collect operation
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   164
 * @since 1.8
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   165
 */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   166
public interface Collector<T, R> {
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   167
    /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   168
     * A function that creates and returns a new result that represents
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   169
     * "no values".  If the accumulator or combiner functions may mutate their
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   170
     * arguments, this must be a new, empty result container.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   171
     *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   172
     * @return a function which, when invoked, returns a result representing
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   173
     * "no values"
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   174
     */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   175
    Supplier<R> resultSupplier();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   176
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   177
    /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   178
     * A function that folds a new value into a cumulative result.  The result
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   179
     * may be a mutable result container or a value.  The accumulator function
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   180
     * may modify a mutable container and return it, or create a new result and
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   181
     * return that, but if it returns a new result object, it must not modify
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   182
     * any of its arguments.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   183
     *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   184
     * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   185
     * characteristic, then the accumulator function <em>must</em> always return
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   186
     * its first argument, after possibly mutating its state.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   187
     *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   188
     * @return a function which folds a new value into a cumulative result
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   189
     */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   190
    BiFunction<R, T, R> accumulator();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   191
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   192
    /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   193
     * A function that accepts two partial results and merges them.  The
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   194
     * combiner function may fold state from one argument into the other and
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   195
     * return that, or may return a new result object, but if it returns
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   196
     * a new result object, it must not modify the state of either of its
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   197
     * arguments.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   198
     *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   199
     * <p>If the collector has the {@link Characteristics#STRICTLY_MUTATIVE}
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   200
     * characteristic, then the combiner function <em>must</em> always return
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   201
     * its first argument, after possibly mutating its state.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   202
     *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   203
     * @return a function which combines two partial results into a cumulative
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   204
     * result
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   205
     */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   206
    BinaryOperator<R> combiner();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   207
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   208
    /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   209
     * Returns a {@code Set} of {@code Collector.Characteristics} indicating
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   210
     * the characteristics of this Collector.  This set should be immutable.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   211
     *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   212
     * @return an immutable set of collector characteristics
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   213
     */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   214
    Set<Characteristics> characteristics();
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   215
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   216
    /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   217
     * Characteristics indicating properties of a {@code Collector}, which can
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   218
     * be used to optimize reduction implementations.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   219
     */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   220
    enum Characteristics {
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   221
        /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   222
         * Indicates that this collector is <em>concurrent</em>, meaning that
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   223
         * the result container can support the accumulator function being
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   224
         * called concurrently with the same result container from multiple
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   225
         * threads. Concurrent collectors must also always have the
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   226
         * {@code STRICTLY_MUTATIVE} characteristic.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   227
         *
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   228
         * <p>If a {@code CONCURRENT} collector is not also {@code UNORDERED},
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   229
         * then it should only be evaluated concurrently if applied to an
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   230
         * unordered data source.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   231
         */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   232
        CONCURRENT,
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   233
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   234
        /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   235
         * Indicates that the result container has no intrinsic order, such as
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   236
         * a {@link Set}.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   237
         */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   238
        UNORDERED,
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   239
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   240
        /**
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   241
         * Indicates that this collector operates by strict mutation of its
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   242
         * result container. This means that the {@link #accumulator()} and
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   243
         * {@link #combiner()} functions will always modify the state of and
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   244
         * return their first argument, rather than returning a different result
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   245
         * container.
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   246
         */
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   247
        STRICTLY_MUTATIVE
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   248
    }
87067e3340d3 8008682: Inital Streams public API
briangoetz
parents:
diff changeset
   249
}