Java8 Lambda表达式的特快处理流Stream快速入门
Stream
什么是Stream?
Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,因为Java正在将自己变的更高(Sha)级(Gua),更人性化。--------可以这么说lambda表达式其实就是实现SAM接口的语法糖。
Java8中,Collection新增了两个流方法。分别是Stream()和parallelStream()
Java8中添加了一个新的接口类Stream,相当于高级的Iteratpr。它可以通过Lambda表达式对集合进行大批量数据操作。或者各种非常便利,高效的聚合数据操作。
为什么要使用Stream?
总结一下本人最常用的场景。在工作中我们经常需要操作数据库。往往会出现一个方法中就需要对一个表的数据进行多次访问。例如我一个方法要做三次数据库操作。一次要计算总条数(count),一次要查询数据(select *),一次要对某些数据查询并进行累加(sum)等等。
三次都操作数据库不是不可以。但是过于频繁的访问数据库,无疑会增加网络传输的消耗,也会增加MySQL服务器的压力。那么,我们的目就转移到了,如何在减少与数据库访问的情况下完成这些业务逻辑。
此时,我们可以用将要查询的数据全部从数据库中获取到一个集合中,在这个集合中,根据不同的条件,过滤出我们想要的数据。如何高效的用代码在集合中过滤出我们想要的数据呢?
Java8之前,我们通常是通过for循环或者Iterator迭代来重排序合并数据,又或者通过重新定义Collections.sorts的Comparator方法来实现。这两种方式对于大数据量系统来说,效率并不是很理想。
Stream的聚合操作与数据库SQL的聚合操作sorted,filter,map等类似。我们在应用层就可以高效地实现类似数据库SQL的聚合操作了。而在数据操作方面,Stream不仅可以通过串行的方式实现数据操作,还可以通过并行的方式处理大批量数据,提高数据的处理效率。
Stream简单例子之筛选查询
如果我们需要从一个list中根据某个条件筛选查询,不使用Stream的方式如下:
需要6行代码完成。
使用Stream改进后:
Stream操作API
官方将Stream中的操作分为两大类:终结操作和中间操作。
中间操作会返回一个新的流,一个流可以后面跟随零个或多个中间操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个流操作使用。这类操作都是惰性化的(lazy),也就是说,仅仅调用到这个类,还没有开始流的遍历(其实就是给接下来的终结操作先加入条件)。而真正的流遍历是在终结操作开始的时候才真正开始执行。
中间操作又可以分为无状态(Stateless)与有状态(Stateful)操作。无状态是指元素的处理不受之前元素的影响。有状态是指该操作需要在之前的操作的基础上继续执行。
终结操作是指返回最终的结果。一个流只能有一个终结操作。当这个操作执行后,这个流就被用”光”了,无法再被操作。所以这必定是这个流的最后一个操作。终结操作才会开始进行流的遍历,并且生成结果。
终结操作又可以分为短路与非短路。
短路是指遇到某些符合条件的元素就可以得到最终结果。
非短路是指必须处理完所有元素才能得到最终结果。操作分类详情如下:
因为Stream操作类型非常多,总结一下常用的:
1. mapToXXX():将流中的原本类型的元素挨个加工变为XXX类型元素,常搭配sum()使用。
2. filter():对流中的元素进行遍历筛选,流下符合条件的数据组成新的流。
3. limit():返回指定数量的流元素。返回的是Stream里前n个元素。
4. skip():将指定数量的元素从流程排除,剩下的元素组成新的流并返回。
5. sorted():将流中的元素按自然排序进行排序。
6. distinct():将流中的元素去重后输出。
7. map():将流中的元素进行再次加工形成一个新的流(常用的有整个流留的小写转大写,以及List<Object>转其中某个元素List<Integer>)
8. peek():与map类似,但与map的区别是它相当于在操作的时候生成一个新的流,并且该操作不会影响到原本流的执行结果。因此基本用于debug。
9. collect():就整个流进行集合转换(转为list,set,map等)
Stream的底层实现
Stream操作叠加
一个Stream的各个操作是由处理管道组装。并统一完成数据处理的。
我们知道Stream有中间操作和终结操作,那么对于一个写好的Stream处理代码来说,中间操作是通过AbstractPipeline生成了一个中间操作Sink链表。当我们调用终结操作时,会生成一个最终的ReducingSink。通过这个ReducingSink触发之前的中间操作,从最后一个ReducingSink开始,递归产生一个Sink链。因此说Stream是惰性化的。如下图所示:
Stream的peek()和map()的区别
刚开始使用Stream的时候,看定义没懂peek是什么意思。看代码感觉用法和map很像。那么二者之间的区别是什么呢?
现有如下代码:
可以看到我们map()在执行打印时编译会报错,这是为什么呢?
从peek方法中,我们看到形参是Consumer。Consumer是没有返回值的,它只是对Stream中的元素进行某些操作。但是操作之后并不会影响整个流的数据。因此后续打印返回的依旧是原来的元素。
可以看到map方法中,形参是Function。Function是返回值的。所以经过map中间操作的流都会收到该操作影响。
而又由于它们各自的特性,打印操作这种无法返回值的就交给peek来处理。而大小写转换这种操作就交给map来处理。
因此,我们常常使用peek作为中间操作的”debug”。
Stream的其它案例
现有一个List
按性别分组
按身高过滤
按身高求和
按身高找最大最小值
Stream的性能
需求
我们写三个方法,寻找list的最小值。来对比他们的执行效率。
常规迭代
串行Stream
-
Java8 Lambda表达式的特快处理流Stream快速入门相关推荐
- 【Java】流(Stream)快速入门
本文是面向Java初学者的流(Stream)学习指导教程.文章内容偏向怎么用,而弱化其诞生背景.流的概念.内部原理等说明解释性的语段. 主要内容: Optional 创建流 操作流 收集流 目录 什么 ...
- Java8 Lambda表达式和流操作如何让你的代码变慢5倍
当本文博主也想尝试着去用stream的方式去处理数据,毕竟代码看上去很简洁,很爽,但是,我就写了这么简单的一句: List<DevUsbUpgradeResult> list = inse ...
- lambda学习视频和stream学习视频(Java8 Lambda表达式视频教程)-Java爬虫-网络购物的正确打开方式
百度网盘 链接:https://pan.baidu.com/s/1upU5EVXOQeho6poDYdnhiQ 提取码:088l Java8 Lambda表达式视频教程 https://www.bil ...
- lambda 对象去重_采用java8 lambda表达式 实现 java list 交集 并集 差集 去重复并集...
采用java8 lambda表达式 实现java list 交集/并集/差集/去重并集 一般的javaList 交.并集采用简单的 removeAll retainAll 等操作,不过这也破坏了原始的 ...
- 采用java8 lambda表达式 实现 java list 交集 并集 差集 去重复并集
采用java8 lambda表达式 实现java list 交集/并集/差集/去重并集 一般的javaList 交.并集采用简单的 removeAll retainAll 等操作,不过这也破坏了原始的 ...
- java8 lambda表达式实现自定义用户组件,Don't Repeat Yourself
2019独角兽企业重金招聘Python工程师标准>>> 一.用户组件的功能 使用java8 lambda表达式实现实现世界的一个例子:用户组件.此用户组件有以下几个操作:获取用户列表 ...
- Java8————Lambda表达式(二)
译者注:文中内容均来自于官方教程<Lambda Expressions>,但是由于英汉语言的差异,部分语句官方描述过于冗余,因此译者根据通常状况的理解做了微调,但不会影响表达的含义.比如: ...
- Java8 Lambda表达式详解手册及实例
先贩卖一下焦虑,Java8发于2014年3月18日,距离现在已经快6年了,如果你对Java8的新特性还没有应用,甚至还一无所知,那你真得关注公众号"程序新视界",好好系列的学习一下 ...
- Java8 lambda表达式,Comparator.comparing().thenComparing()报错
环境 Java:1.8+ 前言 今天发了一个问题: 问题描述: 对List进行排序,如果在Comparator.comparing()方法中,只使用一个字段排序,没有问题. 但是如果使用多字段排序,并 ...
- java8 Lambda表达式的应用(函数式接口、lambda表达式,方法引用及Stream API)
之前写了一篇博客简单介绍了一下java 8发布新增的一些特性功能,java 8在2014年发布,距今也不少年了,但是lambda表达式使用并不熟练,现在一边学习,一边记录一下. 目录 一.Lambda ...
最新文章
- Ubuntu16.04安装NVIDA显卡驱动
- 1007 素数对猜想 (20 分)(c语言)
- leetcode 1074. 元素和为目标值的子矩阵数量(map+前缀和)
- 构建测试的体系化思维(进阶篇)
- 【数据库系统】笛卡尔积与自然连接
- 做一个中国式站长必须知道的五十个问题
- cglib和asm相关的文章
- 芯片电源引脚的电容选择
- echarts折线图怎么从y轴开始_基于echarts的双y轴实时更新折线图
- Redis Cluster部署、管理和测试
- 测试设备和Android机怎么传递消息,在运行2.3的设备上进行测试时,android-Activit......
- Which path should be used jdk or jre for JAVA_HOME environment variable?
- 深夜不眠,爬起来写博客
- Linux安装nginx详细步骤
- 【论文】图文解读经典之作Span-Graph for SRL - 一篇经典的语义角色标注paper
- jic标准_美标JIC是什么螺纹
- 在vue中使用plupload上传图片到七牛(着重解决moxie is not defined问题)
- Spring中的IOC和AOP是什么意思?
- 电脑开机黑屏错误代码U盘重装系统教学
- 电脑怎么保存网页到桌面上使用
热门文章
- 【Java】流(Stream)快速入门