java8 lambda map<list>排序_SpringBoot系列(七):Java8的Stream API,让集合操作更为高效...

本文我们将开个小插曲,分享介绍如何基于Java8提供的Stream特性,高效操作我们的集合,如List、Set、Map等等。其中,将主要介绍Stream特性提供的筛选过滤功能Filter、对象转化功能Map、去重Distinct、排序Sorted、最小值Min以及最大值Max等核心操作。

了解过jdk动态的小伙伴们估计都知道,jdk已经出到12的版本了(是不是有点怀疑目前仍然还在使用jdk1.6、jdk1.5的自己),当然啦,我们都知道,不管jdk怎么升级,其底层核心数据库以及jvm的特性是变化不大的,特别是java8之后的版本,其主要还是以java8作为奠基进行一步步扩张的。如下图所示:

43545aeecc11191ed548b41badbb0e51.png

Java8对外提供的特性有很多,Stream便是其中的一大功能特性,除此之外,Java8还提供了接口默认方法、Lambda表达式、函数式接口等等。说起Java8的Stream,其在集合的操作中着实发挥了强大的作用,别的不说,其中的简洁、高效就特别令人眼前一亮。

Stream作为Java8的新特性,主要是基于lambda表达式,是对集合对象功能的增强,它专注于对集合对象进行各种高效、便利的聚合操作或者大批量的数据操作,可以提高编程的效率和代码可读性。

对于Stream的原理,正是其字面上的含义,Stream是将等待被处理的元素看做一种流,而流在管道中传输,并且可以在管道的节点上执行相应的处理操作,包括过滤筛选、去重、排序、聚合等等,元素流在管道中经过中间操作的处理,最后由最终操作如collect等方法得到前面处理的结果。

对于Stream的原理,各位小伙伴也可以网上搜索相应的文章进行深入的研究,在这里我们只做简单性的介绍。在后续的代码实战中,各位小伙伴可以看到上述对于Stream的原理将很好地在代码中得到体现。

值得一提的是,Stream API在执行的具体操作之前,需要先生成“流”,主要有两种方式:

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

parallelStream() - 为集合创建并行流

下面,我们在com.debug.springboot.server.dto目录下新建一个实体类PersonDto,用于后续的Stream代码实战中,其源代码如下所示:

@Data@AllArgsConstructor@NoArgsConstructor@EqualsAndHashCodepublic class PersonDto implements Serializable{ private Integer id; private Integer age; private String name;}

其中,我们需要在该实体类中加入Equals()和HashCode()方法,用于后续执行Stream的去重API做铺垫!

另外,也需要在com.debug.springboot.server.utils 包目录下新建一个Java8Util类,用于介绍一些比较突出的Steam API操作。

首先,我们需要在Java8Util类中新建一个可以被共用的对象集合,并采用static静态代码块进行初始化,如下所示:

private static List list; //初始化对象集合 static { list= Lists.newLinkedList(); PersonDto dto1=new PersonDto(1,21,"赵六"); PersonDto dto2=new PersonDto(2,20,"张三"); PersonDto dto3=new PersonDto(3,22,"李四"); PersonDto dto4=new PersonDto(4,20,"王五"); list.add(dto1); list.add(dto2); list.add(dto3); list.add(dto4); }

1、首先介绍Stream的筛选过滤功能Filter:下面的代码用于筛选过滤出年龄>20的对象集合,筛选过滤出名字为 王五 的对象信息,如下所示:

//筛选功能:filter 结合 collect方法 使用 public static void method1(){ //筛选年龄大于20的小伙子 if (list!=null && !list.isEmpty()){ System.out.println("--filter筛选功能1,结果:"); List resList=list.stream().filter(p -> p.getAge() > 20).collect(Collectors.toList()); System.out.println(resList); } //筛选名字为 王五 的小伙子 if (list!=null && !list.isEmpty()){ System.out.println("--filter筛选功能2,结果:"); List resList=list.stream().filter(p -> "王五".equals(p.getName())).collect(Collectors.toList()); System.out.println(resList); } }

之后,我们可以写一个main方法,直接调用method1(),其运行结果如下图所示:

86a5fed34ece8af86602331648d09fff.png

2、紧接着,我们介绍Stream中的转换功能Map,如有以下的业务场景:当得到一个对象集合之后,要求我们需要抽取出每个对象中的某个字段,组成新的列表,比如抽取这个对象集合中的Id,或者Name,从而组成新的一个列表,源代码如下所示:

//转换map~按照指定的字段/元素属性进行转换:结合 collect 方法使用 public static void method2(){ if (list!=null && !list.isEmpty()){ System.out.println("--转换map~按照指定的字段/元素属性进行转换,结果:"); Set nameSet=list.stream().map(PersonDto::getName).collect(Collectors.toSet()); System.out.println(nameSet); } }

运行结果如下图所示:

9697fa435ffbbf00790fd93b4e64f0eb.png

3、然后,我们介绍一下“对象去重Distinct”的操作,这一操作,我们需要在实体类中加入 @EqualsAndHashCode 的lombok注解,源代码如下所示:

//去重distinct ~ 配合对象的 equals() 和 hashCode()方法 public static void method3(){ //TODO:对象去重 - 对象需要实现equals hashCode方法 list.add(new PersonDto(4,20,"王五")); System.out.println("去重以前:"+list); List resList=list.stream().distinct().collect(Collectors.toList()); System.out.println("去重以后:"+resList); }

运行结果如下图所示:

d75ae0c4ce1d0af8ebc0bc439aa75485.png

4、顺道,我们介绍一下Stream提供的Sorted排序功能,即我们可以根据对象中的某个字段实施某种排序方式(正序、倒序)等,如下代码所示,我们可以借助Comparator比较器连续先后的对对象集合进行排序:先按照年龄排序、再按照id排序(正序、倒序),源代码如下所示:

//排序sorted public static void method4(){ //按照年龄排序、再按照id排序 list.add(new PersonDto(0,20,"郑六")); if (list!=null && !list.isEmpty()){ List resList=list.stream() .sorted(Comparator.comparingInt(PersonDto::getAge).thenComparing(Comparator.comparing(PersonDto::getId))) .collect(Collectors.toList()); System.out.println("按照年龄排序、再按照id排序-顺序:"+resList); } //按照年龄排序、再按照id排序 ~ 也可以将最终结果倒序来 if (list!=null && !list.isEmpty()){ List resList=list.stream() .sorted(Comparator.comparingInt(PersonDto::getAge).thenComparing(Comparator.comparing(PersonDto::getId)).reversed()) .collect(Collectors.toList()); System.out.println("按照年龄排序、再按照id排序-最终倒序:"+resList); } }

其运行结果如下图所示:

6a663dea0c4077a380881765de08762a.png

5、最后,我们介绍一下如果根据对象中某个字段的最大、最小,从而取出整个对象集合中该最小值字段、最大值字段对应的对象记录,源码如下所示:

//最小min、最大max public static void method5(){ if (list!=null && !list.isEmpty()){ PersonDto p=list.stream() .min(Comparator.comparingInt(PersonDto::getId)) .get(); System.out.println("id最小:"+p); } if (list!=null && !list.isEmpty()){ PersonDto p=list.stream() .max(Comparator.comparingInt(PersonDto::getAge)) .get(); System.out.println("年龄最大:"+p); } }

其运行结果如下图所示:

c2d628a3ece8f22af224ef57bae09b83.png

至此,关于Java8Stream一些常用的操作API,我们已经介绍完毕了,当然啦,除了本文所介绍的一个常用的API操作之外,Stream特性提供的功能操作还远远不止于此,若有小伙伴对Java8的新功能特性感兴趣,可以关注公众号“程序员实战基地”,并回复“java8”,即可免费领取关于java8函数式编程的pdf电子书

补充

1、本文涉及到的相关的源代码可以到此地址,check出来进行查看学习:

https://gitee.com/steadyjack/SpringBootTechnology

2、目前Debug已将本文所涉及的内容整理录制成视频教程,感兴趣的小伙伴可以前往观看学习:

http://www.fightjava.com/web/index/course/detail/5

3、关注一下Debug的技术微信公众号呗,最新的技术文章、技术课程以及技术专栏将会第一时间在公众号发布哦!

推荐阅读:

SpringBoot系列(一):如何构建一个标准的Spring Boot项目

SpringBoot系列(二):如何构建统一的消息响应模型

SpringBoot系列(三):不要告诉我你还不会使用IDEA热部署功能

SpringBoot系列(四):SpringBoot整合Mybatis实现不一样的CRUD

SpringBoot系列(五):SpringBoot整合Mybatis实现多表关联查询

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值