Collectors

The implementation of methods in the Collector interface determines how the flow is reduced. The Collectors class, however, provides many static factory methods that make it easy to create instances of common Collectors and simply use them.

Reduce the operating

  • Collectors.counting

    // Number of sets

    Long collect = employees.stream().collect(Collectors.counting());

    System.out.println(collect);

    System.out.println(employees.stream().count());

    Copy the code
  • Collectors. MaxBy and Collectors. MinBy

    // Maximum and minimum values

    Optional<Employee> collect1 = employees.stream()

      .collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)));

    System.out.println(collect1.get());

    Optional<Employee> collect2 = employees.stream()

      .collect(Collectors.minBy(Comparator.comparingDouble(Employee::getSalary)));

    System.out.println(collect2.get());

    Copy the code
  • Collectors.summingInt

    / / summary

      Integer collect3 = employees.stream().collect(Collectors.summingInt(Employee::getId));

      System.out.println(collect3);

    Copy the code

    SummingLong and Collectors. SummingDouble have the same function and can be used when the summing field is long or double.

    AveragingInt, together with the corresponding averagingLong and averagingDouble, can calculate the average of the values.

    SummarizingInt, summarizingLong, and summarizingDouble compute summation, average, maximum, and minimum values; Get IntSummaryStatistics, LongSummaryStatistics and DoubleSummaryStatistics

  • Collectors.joining

    The collector returned by the joining factory method concatenates all the strings from applying the toString method to each object in the stream into one string.

    // 2 overloaded versions

    List<Employee> employees = EmployeeData.getEmployees();

    String collect = employees.stream().map(Employee::getName)

      .collect(Collectors.joining());

    System.out.println(collect);

    // Add a delimiter

    String collect1 = employees.stream().map(Employee::getName).collect(Collectors.joining(","));

    System.out.println(collect1);

    // Add delimiters, beginning and end

    String collect2 = employees.stream().map(Employee::getName)

      .collect(Collectors.joining(","."The beginning"."The end"));

    System.out.println(collect2);

    Copy the code
  • Collectors.reducing

    Three parameters are required:

    1. The first argument is the starting value of the reduction operation and the return value if there are no elements in the stream, so clearly 0 is a good value for the numeric sum.

    2. Conversion function

    3. Is a BinaryOperator that accumulates two items into a value of the same type

    List<Employee> employees = EmployeeData.getEmployees();

      Integer collect = employees.stream().collect(Collectors.reducing(0, Employee::getId, (a, b) -> a + b));

      System.out.println(collect);

    Optional<Employee> collect3 = employees.stream()

      .collect(Collectors.reducing((a, b) -> a.getSalary() > b.getSalary() ? a : b));

    System.out.println(collect3);



    Optional<Integer> collect1 = Stream.of(1.2.3.4.5).collect(Collectors.reducing((a, b) -> a + b));

    System.out.println(collect1.get());

    Integer collect2 = Stream.of(1.2.3.4.5).collect(Collectors.reducing(10, (a, b) -> a + b));

    System.out.println(collect2);

    Copy the code

grouping

Collectors. GroupingBy.

List<Employee> employees = EmployeeData.getEmployees();

// Group by salary

Map<Double, List<Employee>> collect = employees.stream()

  .collect(Collectors.groupingBy(Employee::getSalary));

System.out.println(collect);

Copy the code
Map<String, List<Employee>> collect1 = employees.stream().collect(Collectors.groupingBy(employee -> {

            if (employee.getSalary() > 9000) {

                return "gao";

            } else if (employee.getSalary() > 500) {

                return "zhong";

            } else {

                return "di";

            }

        }));

System.out.println(collect1);

Copy the code
Operates on grouped elements

The Collectors class overrides the factory method groupingBy. In addition to the usual classification function, its second variable also accepts a Collector type argument.

Map<Double, List<String>> collect2 = employees.stream()

.collect(Collectors.groupingBy(Employee::getSalary, Collectors.mapping(Employee::getName, Collectors.toList())));

System.out.println(collect2);

Copy the code

The Collectors class provides another Collector function through the Mapping method, which takes a mapping function and another Collector function as arguments. The Collector, as a parameter, collects the results of running the mapping function for each element.

There are three parameter overload versions, plus a map generation factory

 HashMap<Double, List<Integer>> collect3 = employees.stream()

   .collect(Collectors.groupingBy(Employee::getSalary, HashMap::new, Collectors

                                  .mapping(Employee::getAge, Collectors.toList())));

Copy the code
Multistage grouping

To achieve multilevel grouping, you can use a collector created by a two-parameter version of the Collectors. GroupingBy factory method, which accepts a second parameter of type Collector in addition to the normal classification function. For secondary grouping, you can pass an inner groupingBy to an outer groupingBy and define a secondary criterion for classifying items in the flow.

 // Multilevel grouping

Map<Double, Map<Integer, List<Employee>>> collect4 = employees.stream().collect

(Collectors.groupingBy(Employee::getSalary,Collectors.groupingBy(Employee::getAge)));

Copy the code
Collect data by subgroup
  • Converts the collector’s results to another type

    Map<Double, Optional<Employee>> collect5 = employees.stream().

       collect(Collectors.groupingBy(Employee::getSalary, Collectors.maxBy(Comparator.comparing(Employee::getName))));



    // Convert the collector's result to another type

    Map<Double, Employee> collect6 = employees.stream().

      collect(Collectors.groupingBy(Employee::getSalary, Collectors.collectingAndThen(Collectors.maxBy(Comparator.comparingInt(Employee::getId)), Optional::get)));   

    Copy the code
  • Additional collectors used in conjunction with groupingBy

     Map<Double, Set<String>> collect7 = employees.stream().collect(

       Collectors.groupingBy(Employee::getSalary, Collectors.mapping(Employee::getName, Collectors.toSet()))); 

    Copy the code

    In combination with other collectors, various types of data can be produced. Continue to explore the use

partition

The partition function returns a Boolean value, which means that the resulting grouped Map has a Boolean key type, so it can be divided into at most two groups — true is a group and false is a group.

 List<Employee> employees = EmployeeData.getEmployees();

 Map<Boolean, List<Employee>> collect = employees.stream()

    .collect(Collectors.partitioningBy(employee -> employee.getSalary() > 1000));

Copy the code

conclusion