Java 8 Stream 简单介绍

简介:

Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据,它位于java.util.stream包下。

Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。

Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。

生成流

在 Java 8 中, 集合接口有两个方法来生成流:

      stream() − 为集合创建串行流。

      parallelStream() − 为集合创建并行流。

方法示例:

public class Employee {
    //员工号
    private Long empno;
    //员工姓名
    private String ename;
    //薪水
    private Integer salary;
    //所属部门号
    private Integer deptno;

    public Employee(Long empno, String ename, Integer salary, Integer deptno) {
        this.empno = empno;
        this.ename = ename;
        this.salary = salary;
        this.deptno = deptno;
    }

  @Override
    public String toString() {
        return "Employee{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", salary=" + salary +
                ", deptno=" + deptno +
                '}';
    }
   //省略get和set方法
}
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);

1. 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}

2. map方法

map方法用于根据自定义的规则对stream流中的数据做一对一的映射
//获取所有员工的姓名
List<String> listName = employees.stream()
                .map(employee -> employee.getEname())
                .collect(Collectors.toList());
        listName.stream().forEach(System.out::println);

执行结果:
SMITH
ALLEN
WARD
CLARK
ADAMS

3. mapToInt/mapToLong/mapToDouble方法

这几个方法主要用来对stream流中的元素产生单个的统计结果
  //获取所有员工的薪水总和
        int totalSalary = employees.stream()
                .mapToInt(employee -> employee.getSalary()).sum();
        System.out.println("薪水总和为:" + totalSalary);

执行结果:
薪水总和:7200

4. 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}

5. 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}

//按员工的薪水由 [ 高到低 ] 排序
List<Employee> sortedEmp = employees.stream()
    .sorted(Comparator.comparing(Employee::getSalary).reversed())
    .collect(Collectors.toList());
sortedEmp.stream().forEach(System.out::println);

执行结果:
Employee{empno=7782, ename='CLARK', salary=2450, deptno=10}
Employee{empno=7499, ename='ALLEN', salary=1600, deptno=30}
Employee{empno=7521, ename='WARD', salary=1250, deptno=30}
Employee{empno=7876, ename='ADAMS', salary=1100, deptno=20}
Employee{empno=7369, ename='SMITH', salary=800, deptno=20}


//先按照员工部门号排序再根据薪资排序
List<Employee> sortList = employees.stream()
    .sorted(Comparator.comparing(Employee::getDeptno).thenComparing(Employee::getSalary))
    .collect(Collectors.toList());
sortList.stream().forEach(rec-> System.out.println(rec));

执行结果:
Employee{empno=7782, ename='CLARK', salary=2450, deptno=10}
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}

6. 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 nameStr= employees.stream()
    .map(employee -> employee.getEname())
    .collect(Collectors.joining(","));
    
System.out.println(nameStr);

执行结果:
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

7. 方法串联

Stream API提供的多个方法可以在一行代码中同时串联使用
//获取20号部门员工姓名,按薪水从高到低排序
List<String> listName= employees.stream()
    .filter(employee -> employee.getDeptno().equals(20))
    .sorted(Comparator.comparing(Employee::getSalary).reversed())
    .map(employee -> employee.getEname())
    .collect(Collectors.toList());

listName.stream().forEach(System.out::println);

执行结果:
ADAMS
SMITH

总结:

 Java8 的Stream API 提供了很多的方法对集合进行过滤,排序等操作,相比较于java7,大大简化了代码的开发量,建议多多使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值