Spec-Zone .ru
спецификации, руководства, описания, API
|
T
- the type of input element to the collect operationR
- the result type of the collect operationpublic interface Collector<T,R>
Collection
; concatenating strings into a
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. Reduction operations can be performed
either sequentially or in parallel.
The following are examples of using the predefined Collector
implementations in Collectors
with the Stream
API to perform
mutable reduction tasks:
// Accumulate elements into a List
List<String> list = stream.collect(Collectors.toList());
// Accumulate elements into a TreeSet
Set<String> list = stream.collect(Collectors.toCollection(TreeSet::new));
// Convert elements to strings and concatenate them, separated by commas
String joined = stream.map(Object::toString)
.collect(Collectors.toStringJoiner(", "))
.toString();
// Find highest-paid employee
Employee highestPaid = employees.stream()
.collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
// Group employees by department
Map<Department, List<Employee>> byDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment));
// Find highest-paid employee by department
Map<Department, Employee> highestPaidByDept
= employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
// Partition students into passing and failing
Map<Boolean, List<Student>> passingFailing =
students.stream()
.collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
A Collector
is specified by three functions that work together to
manage a result or result container. They are: creation of an initial
result, incorporating a new data element into a result, and combining two
results into one. The last function -- combining two results into one -- is
used during parallel operations, where subsets of the input are accumulated
in parallel, and then the subresults merged into a combined result. The
result may be a mutable container or a value. If the result is mutable, the
accumulation and combination functions may either mutate their left argument
and return that (such as adding elements to a collection), or return a new
result, in which case it should not perform any mutation.
Collectors also have a set of characteristics, including
Collector.Characteristics.CONCURRENT
and
Collector.Characteristics.STRICTLY_MUTATIVE
. These characteristics provide
hints that can be used by a reduction implementation to provide better
performance.
Libraries that implement reduction based on Collector
, such as
Stream.collect(Collector)
, must adhere to the following constraints:
resultSupplier()
, accumulator()
,
or combiner()
.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.Collector.Characteristics.UNORDERED
characteristics or if the
originating data is unordered.Collector
should produce a
result equivalent to:
BiFunction<R,T,R> accumulator = collector.accumulator();
R result = collector.resultSupplier().get();
for (T t : data)
result = accumulator.apply(result, t);
return result;
However, the library is free to partition the input, perform the reduction on the partitions, and then use the combiner function to combine the partial results to achieve a parallel reduction. Depending on the specific reduction operation, this may perform better or worse, depending on the relative cost of the accumulator and combiner functions.
An example of an operation that can be easily modeled by Collector
is accumulating elements into a TreeSet
. In this case, the resultSupplier()
function is () -> new Treeset<T>()
, the
accumulator
function is
(set, element) -> { set.add(element); return set; }
, and the combiner
function is (left, right) -> { left.addAll(right); return left; }
.
(This behavior is implemented by
Collectors.toCollection(TreeSet::new)
).
TODO Associativity and commutativity
Stream.collect(Collector)
,
Collectors
Modifier and Type | Interface and Description |
---|---|
static class |
Collector.Characteristics
Characteristics indicating properties of a
Collector , which can
be used to optimize reduction implementations. |
Modifier and Type | Method and Description |
---|---|
BiFunction<R,T,R> |
accumulator()
A function that folds a new value into a cumulative result.
|
Set<Collector.Characteristics> |
characteristics()
Returns a
Set of Collector.Characteristics indicating
the characteristics of this Collector. |
BinaryOperator<R> |
combiner()
A function that accepts two partial results and merges them.
|
Supplier<R> |
resultSupplier()
A function that creates and returns a new result that represents
"no values".
|
Supplier<R> resultSupplier()
BiFunction<R,T,R> accumulator()
If the collector has the Collector.Characteristics.STRICTLY_MUTATIVE
characteristic, then the accumulator function must always return
its first argument, after possibly mutating its state.
BinaryOperator<R> combiner()
If the collector has the Collector.Characteristics.STRICTLY_MUTATIVE
characteristic, then the combiner function must always return
its first argument, after possibly mutating its state.
Set<Collector.Characteristics> characteristics()
Set
of Collector.Characteristics
indicating
the characteristics of this Collector. This set should be immutable.
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.
DRAFT ea-b92