大四学生刚来公司实习,对于一些Java8的特性还不够了解,今天在业务上有一段代码能够帮助自己更好的了解stream流,在各种百度之后,简单谈一下关于stream的各类方法的具体使用。

相信看完本文,大家会对stream流的基本使用方法有一个基本的认识。

凭借个人理解所写,如有不足之处,希望大佬们斧正。

流的使用首先要搞懂lambda表达式

该表达式自Java8引入,简单来讲lambda表达式就是将一段代码赋值给一个变量,如此使用简洁优雅,该表达式所关注的只有两点,一是入参,二是执行逻辑

本文使用了大量的lambda表达式,该表达式箭头左右两侧分别是参数以及执行逻辑,理解本文对于stream流会有一个基本的了解。

该代码的使用场景在于将已经传入的一个dto实体类,实体类中有一个creatorName字段以及一个createdBy字段,接收的时候只有一个createdby字段我们要做的是根据Int类型的createdBy字段在系统数据库里查询相应的数据库里面有个User表User表的id与createdBy是一致的,所以可以根据user表的用户realName设置给creatorname。

关于该代码的上下文

@Overridepublic Page<SoHeader23955> selectList(PageRequest pageRequest, SoHeaderDto dto) {Page<SoHeader23955> page = PageHelper.doPageAndSort(pageRequest, () -> soHeader23955Repository.selectList(Utils.transformObj(dto, SoHeader23955.class)));String userIds = page.getContent().stream().map(l -> l.getCreatedBy().toString()).collect(Collectors.toSet()).stream().collect(Collectors.joining(","));if (StringUtils.isNotEmpty(userIds)) {List<BaseUser> users = baseUserRepository.selectByIds(userIds);page.getContent().forEach(l -> {l.setCreatorName(users.stream().filter(u -> u.getId().equals(l.getCreatedBy())).findFirst().get().getRealName());});}return page;}

要讲解的关于流的代码

String userIds = page.getContent().stream().map(l -> l.getCreatedBy().toString()).collect(Collectors.toSet()).stream().collect(Collectors.joining(","));

最开始page.getContent方法是返回一个list集合(这是利用一个封装好的方法)

之后.stream().map()是将其转换成流的方式,map方法是取出当前流的某个元素,然后对其进行处理。本方法是从一种数据类型转换成新的数据类型,即你可以将一个集合的某一个字段给转换数值类型。在这里我们获得了需要处理的createdBy字段然后使用了toString方法转换成了String类型。在map里你可以对你的数据进行任意地处理然后获取返回值。

之后的 collect(Collectors.toSet())方法是将list集合转换成set集合,原因在于set集合无序且不允许重复,在这里简单给大家看一下三种集合的特点

将转换好的集合再次设置为流(流每一次迭代完毕都会失效)之后使用 collect(Collectors.joining(","),该方法返回的是字符串

到此我们就完成了对一个list数组的某一个int类型字段的无重复化以及转换成String类型的处理。

之后我们就可以根据我们获取得到的id集合获取用户信息了

    List<BaseUser> users = baseUserRepository.selectByIds(userIds);page.getContent().forEach(l -> {l.setCreatorName(users.stream().filter(u -> u.getId().equals(l.getCreatedBy())).findFirst().get().getRealName());});

对这个集合的每个creatorname字段进行处理,首先使用遍历将每个类对象取出来,然后将user表里转换成流使用fliter进行筛选获取第一个值之后getname即可。

我刚开始学的时候对于fliter和foreach还有点懵,其实很简单fliter类似于一个工具一个漏斗将符合条件的字段筛选出来,foreach是对每个成员都进行处理

最后简单谈一下对于学习流的看法,对于新人来说,流的使用确实有点晦涩难懂,我觉得最好的学习方式就是要到实际场景上去尝试,尝试多了就会用了,用多了便很容易理解了,有的时候会用和理解与否并不矛盾。在实际开发中,单个的实体类往往很少用到,用的最多的还是list集合用法,流的使用可以极大地提高效率,还是很有必要去学习的

5.6补充 stream().map的使用

从数据库查询的⽤户集合
现在想获取User的⾝份证号码;在后续的逻辑处理中要⽤;
常⽤的⽅法我们⼤家都知道,⽤for循环,
List idcards=new ArrayList();//定义⼀个集合来装⾝份证号码
for(int i=0;i<users.size();i++){
idcards.add(users.get(i).getIdcard());
}
这种⽅法要写好⼏⾏代码,有没有简单点的,有,java8 API能⼀⾏搞定:
List idcards= users.stream().map(User::getIdcard).collect(Collectors.toList())
解释下⼀这⾏代码:
users:⼀个实体类的集合,类型为List
User:实体类
getIdcard:实体类中的get⽅法,为获取User的idcard

5.10补充

map和foreach的区别查看两者源码发现foreach没有返回值,但是map是有返回值的,因此map是对与集合中的某一个元素进行操作并且返回。

除此之外map集合家还有一个重要特点是map集合是需要和stream流连用的,但是foreach并不需要

void forEach(Consumer<? super T> action);<R> Stream<R> map(Function<? super T, ? extends R> mapper);

粘一段关于foreach使用的代码,可以看到foreach是用来为集合的某个字段设置值的。

   list.forEach(l-> {String code = codeRuleBuilder.generateCode("HZERO.37810.ORDER.NUMBER", null);l.setOrderNumber(code);});

关于map的方法

   // 定义一个 Integer 类型的集合List<Integer> ids = Arrays.asList( 1, 3, 9,  5);
// 获取对应的和ids.stream().map(a-> a+a).forEach(System.out::println);

关于将list结合转换成map,参数列表里面三个参数的问题。

     List<ResultModelLines> modelLines = this.selectByCondition(builder);Map<String, List<String>> tableCodeMap = modelLines.stream().collect(Collectors.toMap(ResultModelLines::getTableCode, item -> Lists.newArrayList(item.getFieldCode()), (a, b) -> {a.addAll(b);return a;}));

第一个参数:ResultModelLines::getTableCode表示选择Person的getId作为map的key值;

第二个参数:item -> Lists.newArrayList(item.getFieldCode())表示选择将原来的对象作为Map的value值

第三个参数:(a,b)->a中,如果a与b的key值相同,选择a作为那个key所对应的value值。

10/31

使用stream流进行多字段去重

到了实际的业务场景中,有的业务需求中,往往某条记录需要多个字段进行去重,这个时候我们就可以使用stream进行多个字段的筛选,在这里我使用了invoiceCode以及invoiceNo两个字段进行校验。

        List<UncertifiedInvoice> uncertifiedInvoices = uncertifiedInvoices1.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(o -> o.getInvoiceCode() + ";" + o.getInvoiceNo()))), ArrayList::new));

11.22更新

使用Stream按照某个字段进行排序

今天在开发中业务需要将我们在查询时,将某些导入的信息按照某个数值字段按照升序排序展示

经过排查后发现是插入时没有按照顺序来插入,因此我们需要再插入之前按照这个字段的数值排序

插入即可,同样的我们使用Stream一行搞定!

关键代码如下

            invoicingOrderHeaderList = invoicingOrderHeaderList.stream().sorted(Comparator.comparing(e -> e.getInvoiceSourceFlag())).collect(Collectors.toList());

Stream流的具体使用讲解相关推荐

  1. Java8 Stream流的常用方法和讲解

    1 Stream概述 Java 8 是一个非常成功的版本,这个版本新增的 Stream,配合同版本出现的 Lambda ,给我们操作集合(Collection)提供了极大的便利. 那么什么是 Stre ...

  2. java 8 Stream流大全,讲解java 8 stream源码内容

    写这篇文章,主要是记录java8 stream流的用法,博主也是查阅了一些资料,结合源码总结出stream流的主要用法,篇幅比较长,需要耐心看. 目录 filter过滤 map获取属性并return值 ...

  3. java8函数式编程之Stream流处理的方法和案例讲解

    函数式编程最早是数学家阿隆佐·邱奇研究的一套函数变换逻辑,又称Lambda Calculus(λ-Calculus),所以也经常把函数式编程称为Lambda计算. 为什么Java需要Lambda表达式 ...

  4. stream流对象的理解及使用

    我的理解:用stream流式处理数据,将数据用一个一个方法去 . (点,即调用) 得到新的数据结果,可以一步达成. 有多种方式生成 Stream Source: 从 Collection 和数组 Co ...

  5. Java8 的 Stream 流式操作之王者归来

    相对于Java8之前的Java的相关操作简直是天差地别,Java8 的流式操作的出现,也很大程度上改变了开发者对于Java的繁琐的操作的印象,从此,Java也走向了函数式编程的道路! 1 流的创建 1 ...

  6. 跟我学 Java 8 新特性之 Stream 流(七)流与迭代器,流系列大结局

    转载自   跟我学 Java 8 新特性之 Stream 流(七)流与迭代器,流系列大结局 恭喜你们,马上就要学完Java8 Stream流的一整系列了,其实我相信Stream流对很多使用Java的同 ...

  7. 跟我学 Java 8 新特性之 Stream 流基础体验

    转载自   跟我学 Java 8 新特性之 Stream 流基础体验 Java8新增的功能中,要数lambda表达式和流API最为重要了.这篇文章主要介绍流API的基础,也是流API系列的第一篇文章, ...

  8. 跟我学 Java 8 新特性之 Stream 流(二)关键知识点

    转载自   跟我学 Java 8 新特性之 Stream 流(二)关键知识点 我们的第一篇文章,主要是通过一个Demo,让大家体验了一下使用流API的那种酣畅淋漓的感觉.如果你没有实践,我还是再次呼吁 ...

  9. 跟我学 Java 8 新特性之 Stream 流(三)缩减操作

    转载自   跟我学 Java 8 新特性之 Stream 流(三)缩减操作 和前面两篇文章一起服用,效果会更佳.通过对流API的基础体验Demo和关键知识点的讲解,相信大家对流API都有一定的认识了, ...

最新文章

  1. linux init进程是所有用户进程的祖先进程,Linux中init进程介绍及常用方法
  2. 一些通讯知识、TCP/IP、三次握手四次分手(正确的图,网上很多错了)、HTTP\HTTPS、DNS、UDP
  3. alexa api php,PHP使用Alexa API获取网站的Alexa排名例子
  4. SQL Server2008(一)简介
  5. MySQL忘记root密码不重启mysqld的方法
  6. Golang 入门笔记(二)下
  7. javascript生成指定范围的随机整数
  8. 02_Flink vs storm vs SparkStreaming、Flink vs storm对比图、实时框架如何选择
  9. git 简易指南+常用命令
  10. linux配置文件为yum,yum的配置文件说明
  11. 安装nginx、drizzle和lua
  12. 华为机试HJ50:四则运算
  13. docker registry push 覆盖_Maven一键部署Springboot到Docker仓库,为自动化做准备
  14. Adblock PLus 插件chrome用
  15. 小米5短接点 | 小米红米高通短接9008教程视频教程 | 高通9008驱动下载 | 不拆机怎么直接进9008 | 什么线能直接进9008
  16. 华为网络计算机ct2000,2019-02-22 华为U2000 ESN查询及License加载
  17. 关于计算机网络以下说法哪个正确().,青书学堂: (多选题) 关于计算机网络,以下说法哪个正确?( )(本题4.0分)...
  18. 如何使用python刷博客浏览量---第一种方法
  19. android 仿微信demo————微信消息界面实现(移动端)
  20. multisim仿真 数码管设计

热门文章

  1. jquery 绘图工具 flot 使用
  2. STM32微控制器SPI接口NSS管理分析
  3. HTML+CSS+js搭建简易网页(1)构建网页的骨架
  4. 恢复通讯录显示服务器开小差,恢复备份数据通讯录还是没有找到数据怎么办?...
  5. 基于JSP动漫论坛的设计与实现(含源文件)
  6. 分解质因数 JAVA
  7. 解决 XCode6 在 iOS7 系统上出现部分黑屏与不适配问题
  8. SAP调研问卷(草稿)
  9. 电机学习笔记 无刷电机控制6步换相
  10. 英文WM 5.0、6.0 ROM汉化初级教程