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
23 * questions.
24 */
25 package java.util.stream;
26
27 import java.util.AbstractMap;
28 import java.util.AbstractSet;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.Comparators;
34 import java.util.DoubleSummaryStatistics;
35 import java.util.EnumSet;
36 import java.util.HashMap;
37 import java.util.HashSet;
38 import java.util.IntSummaryStatistics;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.LongSummaryStatistics;
42 import java.util.Map;
43 import java.util.NoSuchElementException;
44 import java.util.Objects;
45 import java.util.Set;
46 import java.util.StringJoiner;
47 import java.util.concurrent.ConcurrentHashMap;
48 import java.util.concurrent.ConcurrentMap;
49 import java.util.function.BiFunction;
50 import java.util.function.BinaryOperator;
51 import java.util.function.Function;
52 import java.util.function.Predicate;
53 import java.util.function.Supplier;
61 * elements according to various criteria, etc.
62 *
63 * <p>The following are examples of using the predefined {@code Collector}
64 * implementations in {@link Collectors} with the {@code Stream} API to perform
65 * mutable reduction tasks:
66 *
67 * <pre>{@code
68 * // Accumulate elements into a List
69 * List<Person> list = people.collect(Collectors.toList());
70 *
71 * // Accumulate elements into a TreeSet
72 * List<Person> list = people.collect(Collectors.toCollection(TreeSet::new));
73 *
74 * // Convert elements to strings and concatenate them, separated by commas
75 * String joined = stream.map(Object::toString)
76 * .collect(Collectors.toStringJoiner(", "))
77 * .toString();
78 *
79 * // Find highest-paid employee
80 * Employee highestPaid = employees.stream()
81 * .collect(Collectors.maxBy(Comparators.comparing(Employee::getSalary)));
82 *
83 * // Group employees by department
84 * Map<Department, List<Employee>> byDept
85 * = employees.stream()
86 * .collect(Collectors.groupingBy(Employee::getDepartment));
87 *
88 * // Find highest-paid employee by department
89 * Map<Department, Employee> highestPaidByDept
90 * = employees.stream()
91 * .collect(Collectors.groupingBy(Employee::getDepartment,
92 * Collectors.maxBy(Comparators.comparing(Employee::getSalary))));
93 *
94 * // Partition students into passing and failing
95 * Map<Boolean, List<Student>> passingFailing =
96 * students.stream()
97 * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
98 *
99 * }</pre>
100 *
101 * TODO explanation of parallel collection
102 *
103 * @since 1.8
104 */
105 public final class Collectors {
106
107 private static final Set<Collector.Characteristics> CH_CONCURRENT
108 = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
109 Collector.Characteristics.STRICTLY_MUTATIVE,
110 Collector.Characteristics.UNORDERED));
111 private static final Set<Collector.Characteristics> CH_STRICT
112 = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE));
387 * This produces a result equivalent to:
388 * <pre>{@code
389 * reducing(0L, e -> 1L, Long::sum)
390 * }</pre>
391 *
392 * @param <T> the type of the input elements
393 * @return a {@code Collector} that counts the input elements
394 */
395 public static <T> Collector<T, Long>
396 counting() {
397 return reducing(0L, e -> 1L, Long::sum);
398 }
399
400 /**
401 * Returns a {@code Collector<T, T>} that produces the minimal element
402 * according to a given {@code Comparator}.
403 *
404 * @implSpec
405 * This produces a result equivalent to:
406 * <pre>{@code
407 * reducing(Comparators.lesserOf(comparator))
408 * }</pre>
409 *
410 * @param <T> the type of the input elements
411 * @param comparator a {@code Comparator} for comparing elements
412 * @return a {@code Collector} that produces the minimal value
413 */
414 public static <T> Collector<T, T>
415 minBy(Comparator<? super T> comparator) {
416 return reducing(Comparators.lesserOf(comparator));
417 }
418
419 /**
420 * Returns a {@code Collector<T, T>} that produces the maximal element
421 * according to a given {@code Comparator}.
422 *
423 * @implSpec
424 * This produces a result equivalent to:
425 * <pre>{@code
426 * reducing(Comparators.greaterOf(comparator))
427 * }</pre>
428 *
429 * @param <T> the type of the input elements
430 * @param comparator a {@code Comparator} for comparing elements
431 * @return a {@code Collector} that produces the maximal value
432 */
433 public static <T> Collector<T, T>
434 maxBy(Comparator<? super T> comparator) {
435 return reducing(Comparators.greaterOf(comparator));
436 }
437
438 /**
439 * Returns a {@code Collector<T, Long>} that produces the sum of a
440 * long-valued function applied to the input element.
441 *
442 * @implSpec
443 * This produces a result equivalent to:
444 * <pre>{@code
445 * reducing(0L, mapper, Long::sum)
446 * }</pre>
447 *
448 * @param <T> the type of the input elements
449 * @param mapper a function extracting the property to be summed
450 * @return a {@code Collector} that produces the sum of a derived property
451 */
452 public static <T> Collector<T, Long>
453 sumBy(Function<? super T, Long> mapper) {
454 return reducing(0L, mapper, Long::sum);
455 }
474 * @see #reducing(Object, Function, BinaryOperator)
475 */
476 public static <T> Collector<T, T>
477 reducing(T identity, BinaryOperator<T> op) {
478 return new CollectorImpl<>(() -> identity, (r, t) -> (r == null ? t : op.apply(r, t)), op);
479 }
480
481 /**
482 * Returns a {@code Collector<T,T>} which performs a reduction of its
483 * input elements under a specified {@code BinaryOperator}.
484 *
485 * @apiNote
486 * The {@code reducing()} collectors are most useful when used in a
487 * multi-level reduction, downstream of {@code groupingBy} or
488 * {@code partitioningBy}. To perform a simple reduction on a stream,
489 * use {@link Stream#reduce(BinaryOperator)} instead.
490 *
491 * <p>For example, given a stream of {@code Person}, to calculate tallest
492 * person in each city:
493 * <pre>{@code
494 * Comparator<Person> byHeight = Comparators.comparing(Person::getHeight);
495 * BinaryOperator<Person> tallerOf = Comparators.greaterOf(byHeight);
496 * Map<City, Person> tallestByCity
497 * = people.stream().collect(groupingBy(Person::getCity, reducing(tallerOf)));
498 * }</pre>
499 *
500 * @implSpec
501 * The default implementation is equivalent to:
502 * <pre>{@code
503 * reducing(null, op);
504 * }</pre>
505 *
506 * @param <T> element type for the input and output of the reduction
507 * @param op a {@code BinaryOperator<T>} used to reduce the input elements
508 * @return a {@code Collector} which implements the reduction operation
509 *
510 * @see #reducing(Object, BinaryOperator)
511 * @see #reducing(Object, Function, BinaryOperator)
512 */
513 public static <T> Collector<T, T>
514 reducing(BinaryOperator<T> op) {
515 return reducing(null, op);
516 }
517
518 /**
519 * Returns a {@code Collector<T,U>} which performs a reduction of its
520 * input elements under a specified mapping function and
521 * {@code BinaryOperator}. This is a generalization of
522 * {@link #reducing(Object, BinaryOperator)} which allows a transformation
523 * of the elements before reduction.
524 *
525 * @apiNote
526 * The {@code reducing()} collectors are most useful when used in a
527 * multi-level reduction, downstream of {@code groupingBy} or
528 * {@code partitioningBy}. To perform a simple reduction on a stream,
529 * use {@link Stream#reduce(BinaryOperator)} instead.
530 *
531 * <p>For example, given a stream of {@code Person}, to calculate the longest
532 * last name of residents in each city:
533 * <pre>{@code
534 * Comparator<String> byLength = Comparators.comparing(String::length);
535 * BinaryOperator<String> longerOf = Comparators.greaterOf(byLength);
536 * Map<City, String> longestLastNameByCity
537 * = people.stream().collect(groupingBy(Person::getCity,
538 * reducing(Person::getLastName, longerOf)));
539 * }</pre>
540 *
541 * @param <T> the type of the input elements
542 * @param <U> the type of the mapped values
543 * @param identity the identity value for the reduction (also, the value
544 * that is returned when there are no input elements)
545 * @param mapper a mapping function to apply to each input value
546 * @param op a {@code BinaryOperator<U>} used to reduce the mapped values
547 * @return a {@code Collector} implementing the map-reduce operation
548 *
549 * @see #reducing(Object, BinaryOperator)
550 * @see #reducing(BinaryOperator)
551 */
552 public static <T, U>
553 Collector<T, U> reducing(U identity,
554 Function<? super T, ? extends U> mapper,
555 BinaryOperator<U> op) {
|
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
23 * questions.
24 */
25 package java.util.stream;
26
27 import java.util.AbstractMap;
28 import java.util.AbstractSet;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Comparator;
33 import java.util.DoubleSummaryStatistics;
34 import java.util.EnumSet;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.IntSummaryStatistics;
38 import java.util.Iterator;
39 import java.util.List;
40 import java.util.LongSummaryStatistics;
41 import java.util.Map;
42 import java.util.NoSuchElementException;
43 import java.util.Objects;
44 import java.util.Set;
45 import java.util.StringJoiner;
46 import java.util.concurrent.ConcurrentHashMap;
47 import java.util.concurrent.ConcurrentMap;
48 import java.util.function.BiFunction;
49 import java.util.function.BinaryOperator;
50 import java.util.function.Function;
51 import java.util.function.Predicate;
52 import java.util.function.Supplier;
60 * elements according to various criteria, etc.
61 *
62 * <p>The following are examples of using the predefined {@code Collector}
63 * implementations in {@link Collectors} with the {@code Stream} API to perform
64 * mutable reduction tasks:
65 *
66 * <pre>{@code
67 * // Accumulate elements into a List
68 * List<Person> list = people.collect(Collectors.toList());
69 *
70 * // Accumulate elements into a TreeSet
71 * List<Person> list = people.collect(Collectors.toCollection(TreeSet::new));
72 *
73 * // Convert elements to strings and concatenate them, separated by commas
74 * String joined = stream.map(Object::toString)
75 * .collect(Collectors.toStringJoiner(", "))
76 * .toString();
77 *
78 * // Find highest-paid employee
79 * Employee highestPaid = employees.stream()
80 * .collect(Collectors.maxBy(Comparator.comparing(Employee::getSalary)));
81 *
82 * // Group employees by department
83 * Map<Department, List<Employee>> byDept
84 * = employees.stream()
85 * .collect(Collectors.groupingBy(Employee::getDepartment));
86 *
87 * // Find highest-paid employee by department
88 * Map<Department, Employee> highestPaidByDept
89 * = employees.stream()
90 * .collect(Collectors.groupingBy(Employee::getDepartment,
91 * Collectors.maxBy(Comparator.comparing(Employee::getSalary))));
92 *
93 * // Partition students into passing and failing
94 * Map<Boolean, List<Student>> passingFailing =
95 * students.stream()
96 * .collect(Collectors.partitioningBy(s -> s.getGrade() >= PASS_THRESHOLD);
97 *
98 * }</pre>
99 *
100 * TODO explanation of parallel collection
101 *
102 * @since 1.8
103 */
104 public final class Collectors {
105
106 private static final Set<Collector.Characteristics> CH_CONCURRENT
107 = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.CONCURRENT,
108 Collector.Characteristics.STRICTLY_MUTATIVE,
109 Collector.Characteristics.UNORDERED));
110 private static final Set<Collector.Characteristics> CH_STRICT
111 = Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.STRICTLY_MUTATIVE));
386 * This produces a result equivalent to:
387 * <pre>{@code
388 * reducing(0L, e -> 1L, Long::sum)
389 * }</pre>
390 *
391 * @param <T> the type of the input elements
392 * @return a {@code Collector} that counts the input elements
393 */
394 public static <T> Collector<T, Long>
395 counting() {
396 return reducing(0L, e -> 1L, Long::sum);
397 }
398
399 /**
400 * Returns a {@code Collector<T, T>} that produces the minimal element
401 * according to a given {@code Comparator}.
402 *
403 * @implSpec
404 * This produces a result equivalent to:
405 * <pre>{@code
406 * reducing(BinaryOperator.minBy(comparator))
407 * }</pre>
408 *
409 * @param <T> the type of the input elements
410 * @param comparator a {@code Comparator} for comparing elements
411 * @return a {@code Collector} that produces the minimal value
412 */
413 public static <T> Collector<T, T>
414 minBy(Comparator<? super T> comparator) {
415 return reducing(BinaryOperator.minBy(comparator));
416 }
417
418 /**
419 * Returns a {@code Collector<T, T>} that produces the maximal element
420 * according to a given {@code Comparator}.
421 *
422 * @implSpec
423 * This produces a result equivalent to:
424 * <pre>{@code
425 * reducing(BinaryOperator.maxBy(comparator))
426 * }</pre>
427 *
428 * @param <T> the type of the input elements
429 * @param comparator a {@code Comparator} for comparing elements
430 * @return a {@code Collector} that produces the maximal value
431 */
432 public static <T> Collector<T, T>
433 maxBy(Comparator<? super T> comparator) {
434 return reducing(BinaryOperator.maxBy(comparator));
435 }
436
437 /**
438 * Returns a {@code Collector<T, Long>} that produces the sum of a
439 * long-valued function applied to the input element.
440 *
441 * @implSpec
442 * This produces a result equivalent to:
443 * <pre>{@code
444 * reducing(0L, mapper, Long::sum)
445 * }</pre>
446 *
447 * @param <T> the type of the input elements
448 * @param mapper a function extracting the property to be summed
449 * @return a {@code Collector} that produces the sum of a derived property
450 */
451 public static <T> Collector<T, Long>
452 sumBy(Function<? super T, Long> mapper) {
453 return reducing(0L, mapper, Long::sum);
454 }
473 * @see #reducing(Object, Function, BinaryOperator)
474 */
475 public static <T> Collector<T, T>
476 reducing(T identity, BinaryOperator<T> op) {
477 return new CollectorImpl<>(() -> identity, (r, t) -> (r == null ? t : op.apply(r, t)), op);
478 }
479
480 /**
481 * Returns a {@code Collector<T,T>} which performs a reduction of its
482 * input elements under a specified {@code BinaryOperator}.
483 *
484 * @apiNote
485 * The {@code reducing()} collectors are most useful when used in a
486 * multi-level reduction, downstream of {@code groupingBy} or
487 * {@code partitioningBy}. To perform a simple reduction on a stream,
488 * use {@link Stream#reduce(BinaryOperator)} instead.
489 *
490 * <p>For example, given a stream of {@code Person}, to calculate tallest
491 * person in each city:
492 * <pre>{@code
493 * Comparator<Person> byHeight = Comparator.comparing(Person::getHeight);
494 * BinaryOperator<Person> tallerOf = BinaryOperator.greaterOf(byHeight);
495 * Map<City, Person> tallestByCity
496 * = people.stream().collect(groupingBy(Person::getCity, reducing(tallerOf)));
497 * }</pre>
498 *
499 * @implSpec
500 * The default implementation is equivalent to:
501 * <pre>{@code
502 * reducing(null, op);
503 * }</pre>
504 *
505 * @param <T> element type for the input and output of the reduction
506 * @param op a {@code BinaryOperator<T>} used to reduce the input elements
507 * @return a {@code Collector} which implements the reduction operation
508 *
509 * @see #reducing(Object, BinaryOperator)
510 * @see #reducing(Object, Function, BinaryOperator)
511 */
512 public static <T> Collector<T, T>
513 reducing(BinaryOperator<T> op) {
514 return reducing(null, op);
515 }
516
517 /**
518 * Returns a {@code Collector<T,U>} which performs a reduction of its
519 * input elements under a specified mapping function and
520 * {@code BinaryOperator}. This is a generalization of
521 * {@link #reducing(Object, BinaryOperator)} which allows a transformation
522 * of the elements before reduction.
523 *
524 * @apiNote
525 * The {@code reducing()} collectors are most useful when used in a
526 * multi-level reduction, downstream of {@code groupingBy} or
527 * {@code partitioningBy}. To perform a simple reduction on a stream,
528 * use {@link Stream#reduce(BinaryOperator)} instead.
529 *
530 * <p>For example, given a stream of {@code Person}, to calculate the longest
531 * last name of residents in each city:
532 * <pre>{@code
533 * Comparator<String> byLength = Comparator.comparing(String::length);
534 * BinaryOperator<String> longerOf = BinaryOperator.greaterOf(byLength);
535 * Map<City, String> longestLastNameByCity
536 * = people.stream().collect(groupingBy(Person::getCity,
537 * reducing(Person::getLastName, longerOf)));
538 * }</pre>
539 *
540 * @param <T> the type of the input elements
541 * @param <U> the type of the mapped values
542 * @param identity the identity value for the reduction (also, the value
543 * that is returned when there are no input elements)
544 * @param mapper a mapping function to apply to each input value
545 * @param op a {@code BinaryOperator<U>} used to reduce the mapped values
546 * @return a {@code Collector} implementing the map-reduce operation
547 *
548 * @see #reducing(Object, BinaryOperator)
549 * @see #reducing(BinaryOperator)
550 */
551 public static <T, U>
552 Collector<T, U> reducing(U identity,
553 Function<? super T, ? extends U> mapper,
554 BinaryOperator<U> op) {
|