java lambda

Collector和Collectors

2019-08-04  本文已影响0人  spraysss

在Stream中有一个名为collect终止操作,其函数声明如下

 <R, A> R collect(Collector<? super T, A, R> collector);

这个操作的作用是将Stream中的T类型元素通过Collector 中的A类型的可变容器,最终reduce为R类型数据
而Collectors是Collecor的工具类,在Collectors里面实现了诸多有用的Collecor
通过上述的说明,你可能还是不太明白,那么举一个小的例子:

 String []strArray={"hello","world"};
 List<String> strList=Arrays.stream(strArray).collect(Collectors.toList());

这个例子将String类型的Stream 通过collect函数收集为一个List类型

Collector

Collector是一个接口,其声明如下:

Interface Collector<T,A,R>

其中的泛型含义如下:

A Collector 由四个函数配合工作:

这些函数的工作流程如下

     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

Collectors

Collectors是对Collector的实现,他包含了很多有用的reduce操作,比如将元素收集到集合之中,统计元素个数,分组等操作

Collectors使用实例

package com.example.lambda;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CollectorsTest {
    static class Employee {
        private String name;
        private int age;
        private int salary;
        private String dept;

        Employee(String name, int age, int salary, String dept) {
            this.name = name;
            this.age = age;
            this.salary = salary;
            this.dept = dept;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int salary) {
            this.salary = salary;
        }

        public String getDept() {
            return dept;
        }

        public void setDept(String dept) {
            this.dept = dept;
        }

        @Override
        public String toString() {
            return "Employee{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", salary=" + salary +
                    ", dept='" + dept + '\'' +
                    '}';
        }
    }

    public static void main(String[] args) {
        Employee e1 = new Employee("e1", 20, 8000, "BS");
        Employee e2 = new Employee("e2", 21, 7500, "BS");
        Employee e3 = new Employee("e3", 22, 7500, "CW");
        Employee e4 = new Employee("e4", 23, 10000, "CW");
        Employee e5 = new Employee("e5", 24, 15000, "IT");
        Employee e6 = new Employee("e6", 25, 16000, "IT");
        Employee e7 = new Employee("e7", 24, 17000, "IT");
        List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5, e6, e7);
        //找出工资最高的员工
        employees.stream().collect(Collectors.maxBy(Comparator.comparingInt(Employee::getSalary))).ifPresent(e -> {
            System.out.println("工资最高的员工是: " + e);
        });
        //员工的平均工资
        Double avgSalary = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
        System.out.println("员工的平均工资为: " + avgSalary);
        //员工名单
        String empNames = employees.stream().map(Employee::getName).collect(Collectors.joining(",", "<", ">"));
        System.out.println("员工名单: " + empNames);

        //分组,先根据部门分组然后根据年龄分组
        Map<String, Map<Integer, List<Employee>>> groupMap = employees.stream().collect(Collectors.groupingBy(Employee::getDept, Collectors.groupingBy(Employee::getAge)));
        System.out.println("先根据部门分组然后根据年龄分组:" + groupMap);
        //各个部门的人数
        Map<String, Long> countMap = employees.stream().collect(Collectors.groupingBy(Employee::getDept, Collectors.counting()));
        System.out.println("各个部门的人数:" + countMap);
    }
}

运行结果:

工资最高的员工是: Employee{name='e7', age=24, salary=17000, dept='IT'}
员工的平均工资为: 11571.42857142857
员工名单: <e1,e2,e3,e4,e5,e6,e7>
先根据部门分组然后根据年龄分组:{BS={20=[Employee{name='e1', age=20, salary=8000, dept='BS'}], 21=[Employee{name='e2', age=21, salary=7500, dept='BS'}]}, CW={22=[Employee{name='e3', age=22, salary=7500, dept='CW'}], 23=[Employee{name='e4', age=23, salary=10000, dept='CW'}]}, IT={24=[Employee{name='e5', age=24, salary=15000, dept='IT'}, Employee{name='e7', age=24, salary=17000, dept='IT'}], 25=[Employee{name='e6', age=25, salary=16000, dept='IT'}]}}
各个部门的人数:{BS=2, CW=2, IT=3}

参考

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html

上一篇 下一篇

猜你喜欢

热点阅读