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>
其中的泛型含义如下:
- T - Stream中包含的元素类型
- A - 中间容器类型
- R - 结果数据类型
A Collector
由四个函数配合工作:
- 创建一个新的容器 (
supplier()
) - 将元素添加到容器中(
accumulator()
) - 将两个容器合并为一个 (
combiner()
) - 对容器执行一个最终的转换 (
finisher()
)
这些函数的工作流程如下
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