1、序言
Java8的重大变化相信没有小伙伴不知道了,即便没有使用过,也多少有些听闻。简单的记录一下一些简单的用法,主要包括lambda表达式和stream流的简单使用。
** 本书内容部分来自书籍《Java8实战》,感兴趣的小伙伴可以了解一下。
定义一个简单的用户实体类,作为后面的例子:
1 | public class User implements Serializable { |
1 | List<User> userList = Arrays.asList(new User("张三", "man", 68, 2), |
2、lambda表达式
个人对lambda使用的最多的地方就是代替了匿名内部类(还有之后和stream流的使用)。
说道匿名内部类,我想使用的比较多的就是集合排序和比较了,之前内部类的方式就不多说了,直接来lambda表达式的造型:
1 | // 分数升序 |
3、stream流
流的使用大致包括三件事:
- 一个数据源(如集合)来执行一个查询;
- 一个中间操作链,形成一条流的流水线
- 一个终端操作,执行流水线,并能生成结果。
3.1 创建stream流
在 Java 8 中, 集合接口有两个方法来生成流:
- stream() − 为集合创建串行流
- parallelStream() − 为集合创建并行流
3.2 中间操作
3.2.1 filter筛选集合
1 | // 筛选分数大于等于60分的用户 |
3.2.2 map、peek映射操作
1 | // map获取userList里的用户名称集合 |
3.2.3 limit、skip截取流
1 | // limit截取集合前两个 |
3.2.4 flatMap扁平流
你可以简单的将它理解为两重for循环(事实并不是,只是一种理解)
1 | // 创建一个新的,没有班级的User集合 |
需要实现目标,根据userList里的用户名称为userList2里的user添加班级:
1 | List<User> collect = userList.stream().flatMap(u1 -> userList2.stream() |
flatMap推荐博客flatMap推荐博客
3.2.5 sorted排序
1 | // 分数升序 |
3.2.6 distinct去重
1 | // 分数去重 |
注意:如果去重判断的是对象,需要重写equals()和hashCode()方法来判断对象是否相同
2021.1.13 更新
按照实体类某个字段去重
1 |
|
按照实体类某几个字段去重
1 | // 按照年龄和备注去重 |
打印结果:
年龄去重结果:[User(id=5, name=张三4, age=17, remark=ac), User(id=1, name=张三, age=18, remark=aa), User(id=3, name=张三2, age=19, remark=ab)]
年龄和备注去重结果:[User(id=5, name=张三4, age=17, remark=ac), User(id=6, name=张三5, age=17, remark=ad), User(id=1, name=张三, age=18, remark=aa), User(id=7, name=张三6, age=18, remark=ae), User(id=3, name=张三2, age=19, remark=ab)]
3.3 终端操作
3.3.1 forEach遍历集合
1 | // 流遍历 |
注意:尽可能少的在forEach里对元素进行增、删、改,特别是使用并行流parallelStream
3.3.2 count返回流中的个数
1 | // 分数到达70的个数 |
3.3.3 collect收集器
个人觉得这是stream流最重要的一环,流的终端操作
3.3.3.1 常见集合收集器
1 | // 将流收集到List集合内 |
在《Java8实战》一书或者很多博客内的收集器写法比较简单,如:collect(toList())
原因在于导包的时候导入了Collectors类的所以静态工厂方法
1 | // collect(Collectors.toList())的导包 |
收集器除了能将数据收集为List,还能收集为常见的其他集合类型,如:
- Collectors.toMap()
- Collectors.toSet()
- Collectors.toCollection()
- Collectors.toCollection(ArrayList::new)
- Collectors.toCollection(LinkedList::new)
- Collectors.toCollection(CopyOnWriteArrayList::new)
- Collectors.toCollection(TreeSet::new)
3.3.3.2 数值流
1、 对象流转数值流
1 | // 分数求和 |
2、 数值流转对象流(boxed()方法)
1 | // 数值流转对象流,不转的话很多方法使用不了 |
3.3.3.3 汇总
IntSummaryStatistics类,包含了总个数、求和、最小值、最大值、平均值
1 | IntSummaryStatistics collect = userList.stream() |
3.3.3.4 连接字符串joining()
将集合中的元素拼成字符串
1 | // 返回 张三李四王五赵六 |
3.3.3.5 分组groupingBy
1 | // 将集合按条件分组,比如按性别 |
3.3.4 reduce规约
很多操作收集器collect里面都有,而且collect里的方法更加简单
1 | // 分数求和 |
3.3.5 查找和匹配
3.3.5.1 匹配anyMatch、allMatch、noneMatch
1 | // 任意一个元素和要求匹配 |
3.3.5.2 查找findAny、findFirst
1 | // 返回第一个元素 |
这两个方法返回的是Optional类,这里之间简单的使用get()方法去获取值,可能会出现空指针异常
4、优化方法
Java8新特性给我们带来了极大的便利,同时也要注意使用方式。从上面的一些例子中可以看出写法是很重复的,即便是导包时将Collectors类中静态方法导入,也不是那么方便,为了解决这样的困境,我们可以考虑别的方式来解决。比如使用IDEA的模板:
4.1 创建模板
File -> Settings -> Editor ->Live Templates -> 点击右边”+” -> Template Group,完成模板组的创建,然后开始创建模板
Abbreviation | Description | Template text |
---|---|---|
filter | 流集合过滤 | stream().filter(u -> $END$) |
filterlist | 集合过滤list | stream().filter(u -> $END$).collect(Collectors.toList()); |
foreach | 集合流遍历 | forEach(System.out::println); |
groupBy | 集合流分组 | collect(Collectors.groupingBy($END$)); |
groupByCount | 分组计数 | collect(Collectors.groupingBy(u -> $END$, Collectors.counting())); |
joining | 流拼装字符串 | collect(Collectors.joining(“,”)); |
limit | 流截取limit | stream().limit($END$) |
limitlist | 流截取list | stream().limit($END$).collect(Collectors.toList()); |
map | 流映射map | stream().map($END$) |
maplist | 流映射list | stream().map($END$).collect(Collectors.toList()); |
sort | 集合升序排序 | sort(Comparator.comparing($END$)); |
sortR | 集合降序排列 | sort(Comparator.comparing($END$).reversed()); |
toList | list收集器 | collect(Collectors.toList()); |
4.2 使用模板
如果有条件,可以使用最新版的IDEA2020.2版,对lambda表达式提供了更好的支持。
2020-09-08 补充 ## 5、使用补充 ### 5.1 Map遍历 **方法一:**
1 | map.forEach((k, v) -> System.out.println(k + "==" + v)); |
1 | map.keySet().stream().forEach(u -> System.out.println(u + "--" + map.get(u))); |
1 | // 创建线程池 |
2020-9-24补充 optional好文推荐:[理解、学习与使用 JAVA 中的 OPTIONAL](https://www.cnblogs.com/zhangboyu/p/7580262.html "理解、学习与使用 JAVA 中的 OPTIONAL")
- 本文作者: tenyears
- 本文链接: https://tenyears94.gitee.io/2020/08/11/Java8新体验--lambda表达式和stream流/
- 版权声明: 本博客所有文章转载请注明出处!