Stream API

  最近在项目中看到了Stream,之前我对它只是泛泛了解,觉得写、看都挺麻烦,不如传统的集合处理方式更加直观、可读性强,但上手敲过后发现Stream原来很方便,颠覆了我对它的看法。

Stream 简介

顾名思义,Stream是“流”的意思,它将 集合 类型数据以流的形式进行处理,把数据想想成河流,举个例子,我可以自上游到下游按顺序安排上洗脸、洗衣服、洗jio三个过程,数据按序流过了这三个过程,最后出来的就是洗jio水
这里要与IOStream进行区分,不要搞混了,IOStream是对字符处理的流,Stream是对集合数据处理

Stream 优势

个人认为,Stream优势的根源就在于 “流” 的数据处理思想,方法的返回值是它自身,这样就可以链式地调用处理方法,让对数据的操作化为一个连续的过程

  • 化繁为简
      对 List 的一系列操作可以串在一起、一气呵成,相比之下,传统的对List的操作会很麻烦,比如需要将List<User>中User对象中的name取出来组成新的List,传统做法对比Stream如下:
传统:
List<User> userList = UserListFactory.get();
ArrayList<String> nameList = new ArrayList<>();
for(User user : userList) {
	nameList.add(user.getName());
}

Stream:
List<String> nameList = UserListFactory.get().stream()// userList转成stream
								.map(user -> user.getName())//userList中的每个user对象对应另一个元素(这里是name)
								.collect(Collectors.toList());// Stream转List
  • 可读性强
      当然,在不懂Stream使用规则的情况下,Stream读起来会有一定难度,但是在熟悉了Stream的规则后,Stream对List的一系列操作会让你很直观地看懂我对List做了哪些操作以及操作的顺序
  • 代码精简
      如上面的例子,传统方式在userList变nameList的过程中,代码是不连续的,是会产生中间变量与中间结果的,而Stream一个语句就做到了。
      如果场景更复杂些,比如要将List转换为Map再转换为List,中间还夹杂着对属性的操作,传统方式的代码量会很多,并且会产生更多无用的中间产物,而Stream一个语句就可以搞得定
Stream 使用

  java.util.Collection接口中有stream()方法,可以得到Stream对象,List、Set、Queue实现了Collection接口,有stream方法的实现,而Map却没有这个方法,但,stream流最后可以以Map的形式输出

  • forEach
      顾名思义,就是迭代集合中的元素,同时对元素进行处理,注意,此方法无返回值。下面的例子就是将userList中每个user元素的年龄都做+1操作
List<User> userList = UserListFactory.get();
userList.stream().forEach(user -> user.setAge(user.getAge() + 1));
  • map
      此方法,是将userList中原本的user元素映射为另一种数据。样例如下,注意,List转为Stream流再经过映射操作再转为List后,是List,集合中元素的数据类型要符合映射结果的数据类型
List<User> userList = UserListFactory.get();
List<Integer> ageList = userList.stream()
						.map(user -> user.getAge() + 1)
						.collect(Collectors.toList());
  • filter
      顾名思义,这个方法的作用是筛选,里面是一个表达式,集合中元素放入表达式中,结果为true则该元素通过,为false则该元素被拦截下来
List<User> userList = UserListFactory.get();
List<User> userList2 = userList.stream()
						.filter(user -> user.getAge() > 18)
						.collect(Collectors.toList());
  • collect
    看了上面的代码,你肯定有一个疑问,为什么每个代码示例后面都有collect方法?集合类型在使用Stream()方法后会转成Stream流类型,collect方法是将Stream流类型格式化为指定格式的数据类型,目前为止我在项目中较常用的是转为List或Map
    注意:下面第一种转Map的方式存在bug!键值都不可以为null,否则会报空指针异常,如果不提前知道这里埋着雷调试代码时就会以泪洗面。。避坑!感兴趣的自行百度“Collectors.toMap空指针”或“Stream List转Map的坑”或自查源码,暂时就不展开说了;采用第二种转Map方式无忧,第二种方式实际就是自己定义Collectors.toMap方法
Stream转List:
像上面一样,stream.collect(Collectors.toList())即可

Strea转Map方式一(有bug):
List<User> userList = UserListFactory.get();
Map<String, User> userMap = userList.stream()
					.collect(Collectors.toMap(User::getName, user -> user));

Stream转Map方式二:
List<User> userList = UserListFactory.get();
HashMap<Object, Object> userMap = userList.stream()
		.collect(
				HashMap::new, 
				(map, user) -> map.put(user.getName(), user), 
				HashMap::putAll);
  • limit
  • sorted
  • flatMap

…未完待续 2021.02.04

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值