Stream还可以像数据库的操作那样处理数据:比如分组、分区、汇总等等。
导入Collectors类中的所有静态方法,使用时不再需要Collectors.去调用,直接使用即可:
importstatic java.util.stream.Collectors.*;
1、数据分组: groupingBy
List<String> views = Lists.newArrayList("wsbs","xafaswzx","b8fw","ad");
Map<Integer, List<String>> res = views.stream().collect(groupingBy(String::length));
//{2=[ad], 4=[wsbs, b8fw], 8=[xafaswzx]}
2、将收集的结果转换为另一种类型: collectingAndThen
Map<Integer, Object> res = views.stream().collect(
groupingBy(String::length, Collectors.collectingAndThen(
Collectors.maxBy(Comparator.comparingInt(String::length)),
Optional::get // 为转换函数,转换最终的数据
))
);
System.out.println(res);
// {2=ad, 4=wsbs, 8=xafaswzx}
3、多级分组: 嵌套使用groupingBy即可
List<String> views = Lists.newArrayList("wsbsq","hello word","b8fw", "word", "wall", "ad");
Map<Object, Map<Object, List<String>>> res = views.stream()
.collect(groupingBy(str -> str.charAt(0), groupingBy(String::length)));
System.out.println(res);
// {a={2=[ad]}, b={4=[b8fw]}, w={4=[word, wall], 5=[wsbsq]}, h={10=[hello word]}}
4、统计子组数据
List<String> views = Lists.newArrayList("wsbsq","hello word","b8fw", "word", "wall", "ad");
Map<Integer, Long> res = views.stream()
.collect(groupingBy(String::length, Collectors.counting()));
System.out.println(res);
// {2=1, 4=3, 5=1, 10=1}
5、数据分区: partitioningBy
分区函数必须返回一个boolean值,也就是说最后的分区组一个是true,一个是false。
List<String> views = Lists.newArrayList("wsbs","1232","b8fw","wsad");
Map<Boolean, List<String>> res = views.stream().collect(
partitioningBy(str -> str.startsWith("ws")));
//{false=[1232, b8fw], true=[wsbs, wsad]}
// 分区中再进行分组
Map<Boolean, Map<Object, List<String>>> res = views.stream().collect(Collectors.partitioningBy(str -> str.startsWith("ws"),
Collectors.groupingBy(String::length)));
//{false={3=[232], 6=[b8sdfw]}, true={2=[ws], 4=[wsad]}}
6、转换成值:maxBy、minBy
List<String> views = Lists.newArrayList("wsbs","xafaswzx","b8fw","ad");
Optional<String> res = views.stream().collect(
minBy(Comparator.comparing(String::length)));
System.out.println(res.get()); //ad
minBy的最终实现: (a, b) -> comparator.compare(a, b) <= 0 ? a : b
maxBy的最终实现: (a, b) -> comparator.compare(a, b) >= 0 ? a : b
7、将流中的数据转换成整型后汇总求和: summingInt
List<String> views = Lists.newArrayList("wsbs","xafaswzx","b8fw","ad");
Integer resInt = views.stream()
.collect(summingInt(String::length));
System.out.println(resInt); //18
若为summingLong,同样输出18
若为summingDouble,则输出18.0
8、拼接字符串: joining
// wsbs-xafaswzx-b8fw-ad
System.out.println(views.stream().map(s -> s).collect(joining("-")));
9、映射: mapping(Person::getLastName, toSet())
即mapping操作可将左参数(lambda表达式,用于对流中元素做变换)产生的数据动态记录到右参数(集合,将变换的结果收集到集合)中,其内部实现也是通过工厂容器 + 累加器 + 组合器来实现的。
而和groupingBy一起使用的收集器一般也是由mapping方法生成的,当然也包含其他方法。
10、Collectors类中的静态工厂方法:
工厂方法 | 返回类型 | 用于 |
toList | List<T> |
把流中的所有数据元素收集到List集合中。 stream.collect(toList()); |
toSet | Set<T> |
把流中的所有数据元素收集到Set集合中,以为Set自身的特性,即不会出现重复 项。stream.collect(toSet()); |
toCollection | Collection<T> |
把流中的数据元素收集你所指定的集合中, list.stream().collect(toCollection(ArrayList::new)); |
counting | Long |
计算流中元素的个数,list.stream().collect(counting()); |
summingInt | Integer |
对流中所有元素上指定的整数属性求和, list.stream().collect(summingInt(User::getAge)); |
averagingInt | Double |
对流中所有元素上指定的整数属性求平均数, list.stream().collect(averagingInt(User::getAge)); |
summarizingInt |
IntSummaryStatistics |
收集流中所有元素上指定的整数属性的统计值,包括最大值、最小值、总数、平均值。 list.stream().collect(summarizingInt(User::getAge)); |
joining | String |
连接流中元素上指定的属性, list.stream().map(s -> s).collect(joining("-")) |
maxBy | Optional<T> |
使用指定的比较器去比较得到流中所有元素上指定属性的最大值, list.stream().collect(maxBy(Comparator.comparing(String::length))) |
minBy | Optional<T> | 使用指定的比较器去比较得到流中所有元素上指定属性的最小值,
list.stream().collect(minBy(Comparator.comparing(String::length))) |
reducing | 规约操作产生的类型 |
从一个累加器的初始值开始,使用BinaryOperator与流中的元素逐个集合,最后将流规约为单个值。 list.stream().collect(reducing(0, UserVO::getAge, Integer::sum)); |
collectingAndThen | 转换函数返回的类型 |
对最终结果转换为另一种类型, list.stream().collect(collectingAndThen(Collectors.toList(), List::size)); |
groupingBy | Map<k, List<T>> |
根据指定的属性来分组, views.stream().collect(groupingBy(String::length)); |
partitioningBy | Map<boolean, List<T>> |
根据指定的属性来分区, views.stream().collect(partitioningBy(str -> str.startsWith("ws")) |
11、11interface Collector<T, A, R>
当遇到不同的业务需求时,可能会需要自己去实现收集器的功能,就必须得实现Collector接口了,大概包含如下几个方法:
1)Supplier<A> supplier();
用于创建并返回一个新的可变结果的容器。
2)BiConsumer<A, T> accumulator();
将元素添加到结果容器中。
3)BinaryOperator<A> combiner();
合并两个结果容器。
4)Function<A, R> finisher();
对结果容器应用最终转换。
5)Set<Characteristics> characteristics();
返回一个不可变的Characteristics集合。
其中Characteristics为一个枚举类,包含这3个值:CONCURRENT、UNORDERED、IDENTITY_FINISH。
UNORDERED:归约结果不受流中项目的遍历和累积顺序的影响。
CONCURRENT:支持多线程同时调用,可进行并行归约,但只有在没有被标识为UNORDERED才用于无序数据源的并行归约。
IDENTITY_FINISH:表示finisher函数返回的是一个恒等函数,可以不用设置。
相关推荐
java记录随笔
简单记录了基于Ubuntu系统中搭建jdk1.8、mysql5.7、Tomcat9环境的方式,同时记录了修改数据库用户密码的过程
随笔记录java的一些基础知识,不停更新中.... 各个章节稍微有点乱,想起来的时候,可以查看一些知识点。 能简单帮助自己复习一下基础知识与原理性知识。
JavaThings-Java安全漫谈笔记相关《 Java安全漫谈》是我在写的一点Java学习相关的随笔,不是很严谨,也不是啥高科技。这个存储库主要是记录并整理一下,附加一些代码。Java安全漫谈目录 人口统计字节码:远程字节码...
现需要开发一款云随笔app,为了方便用户可以方便快捷的记录自己的日常生活、包括旅游、心事、学习笔记等等。用户填写的记录将会同步到云端以免数据的丢失,后继需要添加上传图片功能、云端数据的下拉
基于JAVA幼儿园家园共育平台设计与实现 开发语言 JavaWeb前端语言 开发工具:六年特雷利JIDEA ...童言稚语:每月记录一次幼儿有趣的话语,文字展示。 育儿头条:育儿新闻文章。管理员上传,可评论点赞
java 源码 博客 一杯82年的JAVA 大家好,我是练习时常两年半的JAVA练习生,爱好是 ...博客专用仓库,主要记录一些学习和实践的总结,感兴趣的朋友可以点个watch或star。 随笔 探索JAVA并发 从0.5到1写个RPC框架
列表参考国光大佬的国光的安全随笔记录 安全技能 该技能表不用按顺序进行学习,但是比较高级的我会放最后面,因为我也不会,需要花时间慢慢加。 总结我这几年的一点经验:安全需要学习的技术太多了,特别是红队、...
mfc使用OLE读取Excel文件,工作中的随笔,小小记录下。借鉴了很多大神的博客,如有侵权,请联系删除,谢谢!
Java自动内存管理机制包含两部分:内存分配和内存回收,要想理解内存分配和回收的机制,则需要了解下Java内存区域(Java运行时数据区),这篇随笔将按照下面的线索进行逐步解析:1.Java运行时数据区2.对象“已死”的...
MiaoWu毕业设计-流浪猫收养系统过程随笔记录通知:1.用户关注用户2.关注的用户发帖3.帖子审核结果4.领养申请5.领养审核结果发帖:需发帖人有联系方式帖子详情页 数据获取顺序调整实现头像修改功能修改记录1.修改猫咪...
是我学习前端知识的随笔,记录着我的理解。 从2020年5月28日开始在GitHub上写笔记,之前一直是在自己电脑上写笔记。 希望能给大家带来帮助(目前还不是很完善,后面会一一补充) [toc] 目录 留着再链接到下面的内容...
- java categories : - 随笔 --- 更多信息配置,例如: --- title : "标题" date : " 2020-08-07 " description : 文章摘要 # 隐藏目录 hideToc : false #生成目录 enableToc : true # 博客展示目录 ...
转载的关于Osip的简介,以及基本的原理介绍等
体验.net2.0的优雅(四):Provider、策略、控制反转和依赖注入 泛型最佳实践 asp.net 2.0下嵌套masterpage页的可视化编辑 C# 2.0与泛型 动态调用对象的属性和方法——性能和灵活性兼备的方法 泛型技巧系列:用泛型...