Java 流 (Stream) 使用进阶

135 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

前言

在上一篇文章中,我们介绍了流的概念,以及流和我们Java 8之前的代码对比,也介绍了一些简单的流入门操作,那么今天我们来进行进一步的使用进阶

流使用进阶

查找与匹配

假如我有一个用户类,这个用户类里面有一个Role的角色类的成员变量List<Role> roles,Role的角色类的定义如下:

public class Role {
    private String roleName;
    
    // 英文字符表示角色的类型 admin, normal_user等等
    private String roleEnName;
    
    // 省略Getter Setter
}

public class User {
    private String userName;
    
    private List<Role> roles;
    
    // 省略Getter Setter
}

查找任意匹配

假如我需要查找这个用户是否存在有管理员角色。可以使用anyMatch如下代码:

 public boolean validateAdmin() {
     return this.roles.stream()
     .anyMatch(role -> "admin".equals(role.getEnname()));
 }

查找是否全匹配

假如我需要查找这个用户是否是一个高层,就是他的所属角色是不是都是管理员角色的。可以使用allMatch如下代码:

 public boolean validateAdmin() {
     return this.roles.stream().allMatch(role -> "admin".equals(role.getEnname()));
 }

查找元素是否全部不匹配

假如我需要查找这个用户是一个普通用户,角色里面没有管理员角色。可以使用noneMatch如下代码:

public boolean validateAdmin() {
     return this.roles.stream().noneMatch(role -> "admin".equals(role.getEnname()));
 }

归约操作

在我们日常的编码中,对于一些数据统计,或者数据展示的大屏图,都需要进行一些数据的筛选统计操作,那么Java的流能更好的帮助我们完成这些部分。

元素求和

在Java 8执之前的数组求和的方式,使用for-each循环可能如下:

int sum = 0;
for (int x : nums) {
    sum += x;
}

使用流操作,只需要一行代码即可完成了:

nums.stream().reduce(0, (a, b) -> a + b);
  • 0代表一个初始值
  • BinaryOperator<T>是一个函数式的接口,来将两个元素结合起来产生一个新值,这里用的是lambda (a, b)-> a + b。 也可以随意切换成想乘或者相除或者取余等等,这样子我们就可以将我们的行为参数化了。

最大值或者最小值

求一个数字集合里面的最大值

nums.stream().reduce(Integer::max)

求一个数字集合里面的最小值

nums.stream().reduce(Integer::min)

总结

流的操作还有很多种方式,大家可以从初级的方式开始,然后渐渐深入,对于一些数据处理,先去查找文档,看下是否有对应的流的API实现了。这样也会加深使用的印象