Lambda表达式-聚合操作
文章参考自博客:https://www.cnblogs.com/franson-2016/p/5593080.html
以及学习网站:how2java.cn
1.传统方式和聚合操作遍历数据的不同
传统遍历List的方式如下:
for(Hero h:list){
if(h.getAge()>50 && h.getId()<400)
System.out.println(h.getName());
}
而使用了聚合操作的方式如下:
list
.stream()
.filter( h-> h.getAge()>50 && h.getId()<400)
.forEach(h-> System.out.println(h.getName()));
2.Stream(流)是什么?
Stream是对集合的包装,通常和lambda一起使用。 使用lambdas可以支持许多操作,如 map, filter, limit, sorted, count, min, max, sum, collect 等等。 同样,Stream使用懒运算,他们并不会真正地读取所有数据,遇到像getFirst() 这样的方法就会结束链式语法。
Stream和Collection结构化的数据不同,Stream有一系列的元素
管道指的是一系列的聚合操作的总和
管道由三部分组成:管道源,中间操作,结束操作
(1)管道源: 其可以是一个集合,一个数组,一个生成器函数或一个I / O通道
//管道源是一个集合
list
.stream()
.forEach(h-> System.out.println(h.getName())); //管道源是一个数组
Hero array[] = list.toArray(new Hero[list.size()]); Arrays.stream(array)
.forEach(h-> System.out.println(h.getName()));
(2)零个或多个中间操作: 每个中间操作会返回一个流,如filter,中间操作时懒操作,不会真正遍历
中间操作有很多种,主要分为两种:
1.对元素进行筛选:filter(匹配),distinct(去除重复),sorted(自然排序)
sorted(Comparator)(指定排序),limit(保留),skip(忽略)
2.转为其他形式的流:mapToDouble(转为double的流), map(转换为任意类型的流)
(3)结束操作: 例如forEach,会返回非流结果,例如基本类型的值(int,float,double)、对象或者集合,或者在终端操作为forEach的情况下没有返回值。
结束操作时才真正进行遍历行为,前面的中间操作也在这个时候真正的执行。
常见的结束操作如下:
forEach()(遍历每个元素),toArray()(转换为数组),min(Comparator)(取最小的元素)
max(Comparator)(取最大的元素),count()(总数),findFirst()(第一个元素)
3.具体用例
首先创建一个100个元素的表,用随机数填充其年龄和ID
Random r = new Random(System.currentTimeMillis());
List<Hero> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add(new Hero("hero-"+i,r.nextInt(500),r.nextInt(100)));
}
然后执行各种中间操作:
//用filter筛选满足条件的对象,并进行操作
list
.stream()
.filter(h-> h.getId()<300 && h.getAge()>50)
.forEach(h-> System.out.println(h)); //用distinct去除重复元素
list
.stream()
.distinct()
.forEach(h-> System.out.print(h)); //用sorted进行排序
list
.stream()
.sorted((h1,h2) -> h1.getAge()>h2.getAge() ? 1:-1)
.forEach(h-> System.out.println(h)); //用limit保留三个元素
list
.stream()
.limit(3)
.forEach(h-> System.out.println(h)); //用skip忽略前三个元素
list
.stream()
.skip(3)
.forEach(h-> System.out.println(h)); //用mapToDouble转换为Double的Stream
list
.stream()
.mapToDouble(Hero::getAge)
.forEach(h-> System.out.println(h)); //转换为任意类型的Stream
list
.stream()
.map((h)-> h.getName()+"-"+h.getAge()+"-"+h.getId())
.forEach(h-> System.out.println(h));
终端操作(结束操作)的用例如下:
//用forEach遍历集合
list
.stream()
.forEach(h-> System.out.println(h)); //用toArray将表变为数组
Object[] arrays = list
.stream()
.toArray(); //用min得到最小值
Hero h1 = list
.stream()
.min((hf,hs)->hf.getAge()-hs.getAge())
.get(); //用max得到最大值
Hero h2 =list
.stream()
.max((hf,hs) -> hf.getAge()-hs.getAge())
.get(); //用count计算流中的数据总数
long count = list
.stream()
.count(); //用findFirst得到第一个元素
Hero h3 = list
.stream()
.findFirst()
.get();
测试用例:
Hero h = list
.stream()
.sorted((h1,h2)-> h1.getAge()>h2.getAge() ? -1:1)
.skip(2)
.findFirst()
.get();
Lambda表达式-聚合操作的更多相关文章
- Util应用程序框架公共操作类(十二):Lambda表达式公共操作类(三)
今天在开发一个简单查询时,发现我的Lambda操作类的GetValue方法无法正确获取枚举类型值,以至查询结果错误. 我增加了几个单元测试来捕获错误,代码如下. /// <summary> ...
- Util应用程序框架公共操作类(八):Lambda表达式公共操作类(二)
前面介绍了查询的基础扩展,下面准备给大家介绍一些有用的查询封装手法,比如对日期范围查询,数值范围查询的封装等,为了支持这些功能,需要增强公共操作类. Lambda表达式公共操作类,我在前面已经简单介绍 ...
- MybatisPlus Lambda表达式 聚合查询 分组查询 COUNT SUM AVG MIN MAX GroupBy
一.序言 众所周知,MybatisPlus在处理单表DAO操作时非常的方便.在处理多表连接连接查询也有优雅的解决方案.今天分享MybatisPlus基于Lambda表达式优雅实现聚合分组查询. 由于视 ...
- Util应用程序框架公共操作类(七):Lambda表达式公共操作类
前一篇扩展了两个常用验证方法,本文将封装两个Lambda表达式操作,用来为下一篇的查询扩展服务. Lambda表达式是一种简洁的匿名函数语法,可以用它将方法作为委托参数传递.在Linq中,大量使用La ...
- lambda 表达式定制操作
泛型算法中的定制操作 许多算法都会比较输入序列中的元素以达到排序的效果,通过定制比较操作,可以控制算法按照编程者的意图工作. 普通排序算法: template<class RandomItera ...
- Util应用程序框架公共操作类(九):Lambda表达式扩展
上一篇对Lambda表达式公共操作类进行了一些增强,本篇使用扩展方法对Lambda表达式进行扩展. 修改Util项目的Extensions.Expression.cs文件,代码如下. using Sy ...
- λ(lambda)表达式
理论阶段 函数接口 函数接口是行为的抽象: 函数接口是数据转换器; java.util.Function包.定义了四个最基础的函数接口: Supplier<T>: 数据提供器,可以提供 T ...
- java集合框架之聚合操作stream
参考http://how2j.cn/k/collection/collection-aggregate/702.html#nowhere 聚合操作 JDK8之后,引入了对集合的聚合操作,可以非常容易的 ...
- 超强的Lambda Stream流操作
原文:https://www.cnblogs.com/niumoo/p/11880172.html 在使用 Stream 流操作之前你应该先了解 Lambda 相关知识,如果还不了解,可以参考之前文章 ...
随机推荐
- 使用 ESP8266 制作 WiFi 干扰器 - 无需密码即可使用任何 WiFi
嘿,朋友,我是 Kedar,你有没有想阻止所有的 WiFi信号?或者只是想从 WiFi 踢某人或邻居 WiFi .那么,本玩法是你等待结束的时刻了.这是为你提供的.仅需 $8 的 DIY Wifi 干 ...
- 基于 HTML5 WebGL 的 3D 棉花加工监控系统
前言 现在的棉花加工行业还停留在传统的反应式维护模式当中,当棉花加下厂的设备突然出现故障时,控制程序需要更换.这种情况下,首先需要客户向设备生产厂家请求派出技术人员进行维护,然后生产厂家才能根据情况再 ...
- 关于mysql中unique的插入Duplicate key
MySQL数据库中 如果在后台中不做判断是否unique的column是否存在的话,直接把数据操作给dao层再传给DB的话,就会报重复的唯一值.如果确实是不希望先取出判断unique的column是否 ...
- PHP中的DateTime类
DataTime类跟date(),strtotime(),gmdate()等函数有相同的作用,都是用来处理日期和时间的,但DateTime类更加直观.方便, 所以在PHP5.2.0以后推荐使用Date ...
- simple高度自定义的jqPaginator 项目中做分页的应用技巧
最近做后台管理系统,分页用到的不少,项目中其实已经有分页功能的组件但是不够高度自定义,于是就找到了 jqPaginator 高度自定义的Html结构 初始化引用如下: $("#paginat ...
- Android技术框架——Dagger2
Dagger2 是一个Android依赖注入框架.没错依赖注入,学习过spring的同学看到这词,应该是挺熟悉的.当然既然是Android的课题,我们就来聊聊Dagger2 ,android开发当前非 ...
- Linux(Ubuntu 16) 下Java开发环境的配置(三)------Mysql配置
前言 吐槽一句,如果在Ubuntu在默认情况下是只有最新的MySQL源的,即如果使用"sudo apt-get install mysql-server mysql-client " ...
- python配置文件的加载
背景: 微信机器人项目用到了mysql数据库配置,阿里云OSS上传文件配置:现在需要将这些配置参数统一写到一个配置文件中统一管理,而不是分散的写在代码中 1. 使用.ini文件作为配置文件 例如: s ...
- Atcoder Beginner Contest 124 解题报告
心态爆炸.本来能全做出来的.但是由于双开了Comet oj一个比赛,写了ABC就去搞那个的B题 还被搞死了. 回来写了一会D就过了.可惜比赛已经结束了.真的是作死. A - Buttons #incl ...
- java基础3之IO
流 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接.类似的,当程序需要写入数据的时候,就会开启一个通向目的地的流. 流的种类 字符 ...