Stream 简介
Stream 是 Java8 提供的一个新的 API, 它位于 java.util.stream 包下. Stream API 提供了一种新的方式来对 Java 集合进行操作, 这种操作方式极大的提高了 Java 程序员的生产力, 让程序员写出高效率, 干净, 简洁的代码.
我们可以将元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序, 聚合等. 元素流在管道中经过中间操作的处理, 最后由最终操作得到前面处理的结果
Stream 方法
示例代码
- class Employee {
- private Long empno; // 员工号
- private String ename; // 员工姓名
- private Integer salary; // 薪水
- private Integer deptno; // 所属部门号
- // 此处省略 get/set 方法, 构造方法以及 toString 方法
- }
- Employee e1 = new Employee(7369L, "SMITH", 800, 20);
- Employee e2 = new Employee(7499L, "ALLEN", 1600, 30);
- Employee e3 = new Employee(7521L, "WARD", 1250, 30);
- Employee e4 = new Employee(7782L, "CLARK", 2450, 10);
- Employee e5 = new Employee(7876L, "ADAMS", 1100, 20);
- List<Employee> employees = Arrays.asList(e1, e2, e3, e4, e5);
forEach 方法
forEach 方法用于迭代 stream 流中的每一个元素
employees.stream().forEach(System.out::println);
执行结果:
- Employee{
- empno=7369, ename='SMITH', salary=800, deptno=20
- }
- Employee{
- empno=7499, ename='ALLEN', salary=1600, deptno=30
- }
- Employee{
- empno=7521, ename='WARD', salary=1250, deptno=30
- }
- Employee{
- empno=7782, ename='CLARK', salary=2450, deptno=10
- }
- Employee{
- empno=7876, ename='ADAMS', salary=1100, deptno=20
- }
map 方法
map 方法用于根据自定义的规则对 stream 流中的数据做一对一的映射
- // 获取所有员工的姓名
- List<String> enames = employees.stream().map(employee -> employee.getEname()).collect(Collectors.toList());
- enames.stream().forEach(System.out::println);
执行结果:
- SMITH
- ALLEN
- WARD
- CLARK
- ADAMS
mapToInt/mapToLong/mapToDouble 方法
这几个方法主要用来对 stream 流中的元素产生单个的统计结果
- // 获取所有员工的薪水总和
- int totalSalary = employees.stream().mapToInt(employee -> employee.getSalary()).sum();
- System.out.println("薪水总和:" + totalSalary);
执行结果:
薪水总和: 7200
filter 方法
filter 方法用于根据设置的条件对 stream 流中的数据做过滤操作
- // 获取薪水超过 1500 的员工
- List<Employee> filterEmp = employees.stream().filter(employee -> employee.getSalary()>1500).collect(Collectors.toList());
- filterEmp.stream().forEach(System.out::println);
执行结果:
- Employee{
- empno=7499, ename='ALLEN', salary=1600, deptno=30
- }
- Employee{
- empno=7782, ename='CLARK', salary=2450, deptno=10
- }
sorted 方法
sorted 方法用于对流中的元素进行排序
- // 按员工的薪水由低到高排序
- List<Employee> sortedEmp = employees.stream().sorted(Comparator.comparing(Employee::getSalary)).collect(Collectors.toList());
- sortedEmp.stream().forEach(System.out::println);
执行结果:
- Employee{
- empno=7369, ename='SMITH', salary=800, deptno=20
- }
- Employee{
- empno=7876, ename='ADAMS', salary=1100, deptno=20
- }
- Employee{
- empno=7521, ename='WARD', salary=1250, deptno=30
- }
- Employee{
- empno=7499, ename='ALLEN', salary=1600, deptno=30
- }
- Employee{
- empno=7782, ename='CLARK', salary=2450, deptno=10
- }
Collectors 类
Collectors 类实现了很多归约操作, 例如将流转换成集合和聚合元素. Collectors 可用于返回列表或字符串
- // 按员工所属部门号进行分类
- Map<Integer, List<Employee>> map = employees.stream().collect(Collectors.groupingBy(employee -> employee.getDeptno()));
- for(Map.Entry<Integer, List<Employee>> entry : map.entrySet()) {
- System.out.println("key:" + entry.getKey() + "value:" + entry.getValue());
- }
- System.out.println();
- // 获取员工姓名, 用 "," 进行拼接
- String enameString = employees.stream().map(employee -> employee.getEname()).collect(Collectors.joining(","));
- System.out.println(enameString);
执行结果:
- key: 20 value:[Employee{
- empno=7369, ename='SMITH', salary=800, deptno=20
- }, Employee{
- empno=7876, ename='ADAMS', salary=1100, deptno=20
- }]
- key: 10 value:[Employee{
- empno=7782, ename='CLARK', salary=2450, deptno=10
- }]
- key: 30 value:[Employee{
- empno=7499, ename='ALLEN', salary=1600, deptno=30
- }, Employee{
- empno=7521, ename='WARD', salary=1250, deptno=30
- }]
- SMITH,ALLEN,WARD,CLARK,ADAMS
方法串联
Stream API 提供的多个方法可以在一行代码中同时串联使用
- // 获取 20 号部门员工姓名, 按薪水从高到低排序
- List<String> names = employees.stream().filter(employee -> employee.getDeptno().equals(20)).sorted(Comparator.comparing(Employee::getSalary).reversed()).map(employee -> employee.getEname()).collect(Collectors.toList());
- names.stream().forEach(System.out::println);
执行结果:
ADAMS SMITH
总结
Stream API 提供了多个方法对集合进行映射, 过滤, 排序等操作, 相比于 Java7, 大大简化了代码的开发. 记住: Stream API 中的方法并不会影响原始集合
来源: https://www.cnblogs.com/liantdev/p/10096253.html