Java 8 API 添加了一个新的抽象称为流 Stream,可以让你以一种声明的方式处理数据,它提供了非常强大Java 集合运算和表达的高阶抽象。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理,可以把它看成一个工厂,流水线的形式(假如是玩具厂)。在这个流水线上,工人们对每个过来的玩具,进行处理,比如筛选、组装等。
Stream API可以极大提高Java程序员的生产力,省时省力还优雅。
下面我们来看看它的常见用法:
一、将List提取出某个字段生成List
List<String> userIdList = userList.stream().map(User::getUserId).
collect(Collectors.toList());
这行代码可以将userList中的userId转换为流 再用.collect(Collectors.toList())方法 提取为一个List集合,非常的方便高效。
另外,有的小伙伴可能需要过滤空字符等,可以用Stream流的 filter() 方法
List<String> userAddressList = userList.stream().map(User::getAddress).
filter(Objects::nonNull).
collect(Collectors.toList());
这行代码 可以将userList的地址提取出来,且过滤掉地址为空的user对象。
二、将List根据某个字段生成Map
1、转换成对象某一字段与对象的Map
示例代码如下:
Map<String, User> userIdWithUserMap = userList.stream().
collect(Collectors.toMap(User::getUserId, User-> user));
这段代码可以以userId为key,user对象为value 组成一个map
2、转换成对象某一字段与对象另一字段的Map
示例代码如下:
Map<String, int> userIdWithAgeMap = userList.stream().
collect(Collectors.toMap(User::getUserId, User::getAge));
三、通过Stream流 将一个集合转换为另一个集合
List<UserVo> voList = userList.stream().map(item -> {
UserVo vo = new UserVo();
BeanUtils.copyProperties(item,vo);
//vo可以进行别的操作
//vo.set... 之类的
return vo;
}).collect(Collectors.toList());
上面这段代码通过Stream流的map()方法 可以将每个元素换成别的元素。可以将流看成一个流水线,userList的流一个一个过去 工人们将每个产品都将userList转换为 userVoList。 item是自定义名称 你也可以叫user 甚至a b c等(我不建议我不建议我不建议)
里面是使用了BeanUtils.copyProperties(item,vo); 来进行属性复制的操作。将item对象的属性赋值给vo对象。需要注意的是 item和vo的字段名需要对上 否则无法赋值成功。比如user有id name age三个属性,vo是userId, userName, age 三个属性 这时只有age能成功赋值。别的需要自己去set。
四、通过Stream流的sorted方法进行排序
我们偶尔会遇到想根据集合中的某个属性来进行排序的情况。
假设UserVo中 有个 distance 距离 属性。 我们想根据 distance 排序 怎么实现呢?
Stream流也可以做到:
List<UserVo> resultVoList = voList.stream()
.sorted(Comparator.comparingDouble(UserVo::getDistance))
.collect(Collectors.toList());
上面这行代码 使用了 Stream流的 sorted() 方法 将voList进行排序。 再使用.collect(Collectors.toList()); 将流转换为List集合。巧妙的实现了排序操作。
五、通过Stream流去重
有些小伙伴可能有去重的需求,我们知道set结构是去重的。
那么我们可以利用Stream的Collectors.toSet()来进行
Set<String> userIdSet = userList.stream()
.map(User::getUserId)
.collect(Collectors.toSet());
这段代码就提取出了userList的id,并去重 赋值为一个Set集合。
//有空会继续补充。。
另外有些小伙伴会有疑问说For循环 增强For循环 Stream流 这三个的效率区别 Stream会不会比较慢等。
For循环 增强For循环 Stream流三者差别。
基本上 三者对于List操作 循环效率差别不大。
一定要对比一下的话,在循环次数较少的时候,基本上是Stream流的效率最低。为什么说是基本上,啊因为它大部分情况最低的。但是Stream可以通过parallel()方法开启并行流,随着CPU核心数的提升,和一些合理的场景运用,则会越来越快,这跟它基于的Fork/join框架有关。这个框架简单来说就是将可以并行的任务拆分成更小的任务来并行。后续我再出一篇细讲。
损失的一丁点性能,换来的是代码非常大程度的整洁和优雅。我个人还是非常推荐大家使用Stream流的。
好了。这部分先到这里,还有需要了解什么场景,或者我有些说的不太准确的地方,欢迎大家留言指正。谢谢!