带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(3)

简介: 带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(3)

带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(2)https://developer.aliyun.com/article/1339661?groupCode=taobaotech


原理不少人可能会觉得简单易懂,但遗憾的是在大型项目中往往总能找到有此类性能缺陷的代码,诸如

 

List<Long> awardId = timeFilterAwardConfigs.stream()
.map(config -> config.getAwardId())
.filter(awardId -> awardId > 0)
.collect(Collectors.toList());

 

 

但在更复杂的场景下,也并非要求filter无脑提前于其他操作。比如下面这个例子

 

//假设一份用户集
List<User> userList = Arrays.asList( new User("张三", 22)
, new User("李四", 21)
, new User("王五", 19)
, new User("赵六", 25)
);
//要输出这份集合中所有用户所就职的公司的年度营业额总和,要求公司所在地都在杭州市余杭区
// 注意用户中可能有无业游民。不考虑就职公司重合或者一人就职多家公司的情况。
//写法一
int allCompanyTurnover1 = userList.stream()
.map(user -> calculateAnnualTurnover(queryUserCompany(user)))
.filter(Objects::nonNull)
.reduce(0, Integer::sum);
//写法二
int allCompanyTurnover2 = userList.stream()
.filter(user -> {
Company company = queryUserCompany(user);
return company != null && !"余杭".equals(company.getLocal());
})
.map(user -> calculateAnnualTurnover(queryUserCompany(user)))
.reduce(0, Integer::sum);

 

 

 

写法一显然更符合直觉,写法二虽然filter提前过滤掉了一部分数据,但是queryUserCompany存在重复计算。以此种情况下就需要综filter过滤度和queryUserCompany重复计算的开销进行权衡。如果filter过滤度足够高

(比如余杭的公司很少)同时queryUserCompany 资源开销不大,那么写法二更优,反之写法一更优。

 

并非适用所有场景

 

image.png性能上

这里就可以说回到刚才讲anyMatch时看到的那段代码

 

//判断昨天是否签到过。写法一
boolean yesterdaySigned = calendars.stream()
.anyMatch(
t -> Days.daysBetween(t.getDate(), now).getDays() == 1 && t.isSigned()
);
System.out.println("昨天是否签到过 -> " + yesterdaySigned);
//写法二
boolean yesterdaySigned2 = false; for (Calendar calendar : calendars) {
if (Days.daysBetween(calendar.getDate(), now).getDays() == 1) {
//找到昨天的日历,并判断是否签到yesterdaySigned2 = calendar.isSigned(); break;
}
}
System.out.println("昨天是否签到过写法二 -> " + yesterdaySigned2);

 

带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(4)https://developer.aliyun.com/article/1339659?groupCode=taobaotech

相关文章
《深入理解高并发编程(第2版)》八大篇章,共433页,打包发布!!
大家好,我是冰河~~ 在 冰河技术 微信公众号中的【精通高并发系列】专题,更新了不少文章,有些读者反馈说,在公众号中刷历史文章不太方便,有时会忘记自己看到哪一篇了,当打开一篇文章时,似乎之前已经看过了,但就是不知道具体该看哪一篇了。相信很多小伙伴都会有这样的问题。那怎么办呢? 最好的解决方案就是我把这些文章整理成PDF电子书,免费分享给大家,这样,小伙伴们看起来就方便多了。
1464 0
《深入理解高并发编程(第2版)》八大篇章,共433页,打包发布!!
|
SQL 缓存 Java
mybatis 一对多查询
mybatis 一对多查询
490 0
|
存储 数据可视化 API
重磅干货,免费三方网络验证[用户系统+CDK]全套API接口分享教程。
本套网络验证系统提供全面的API接口,支持用户注册、登录、数据查询与修改、留言板管理等功能,适用于不想自建用户系统的APP开发者。系统还包含CDK管理功能,如生成、使用、查询和删除CDK等。支持高自定义性,包括20个自定义字段,满足不同需求。详细接口参数及示例请参考官方文档。
599 7
|
机器学习/深度学习 人工智能 自然语言处理
大型语言模型如何工作?
大型语言模型如何工作?
|
数据安全/隐私保护 计算机视觉 Python
用python给照片添加水印的三种方式
这篇文章介绍了使用Python给照片添加水印的三种方式:通过PIL库直接添加文本水印、使用OpenCV库结合图像处理功能添加水印,以及使用filestools库进行更为简便的水印添加。
1219 8
|
机器学习/深度学习 API 算法框架/工具
【Tensorflow+keras】Keras API三种搭建神经网络的方式及以mnist举例实现
使用Keras API构建神经网络的三种方法:使用Sequential模型、使用函数式API以及通过继承Model类来自定义模型,并提供了基于MNIST数据集的示例代码。
319 12
|
Linux
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
2389 2
Linux下采集摄像头的图像再保存为JPG图片存放到本地(YUYV转JPG)
|
存储 分布式计算 Hadoop
Hadoop性能问题
【7月更文挑战第12天】
347 11
|
人工智能 安全 算法
5G 网络中的加密:守护你的数据安全
5G 网络中的加密:守护你的数据安全
1251 0
|
存储 关系型数据库 MySQL
如何处理爬取到的数据,例如存储到数据库或文件中?
处理爬取的数据,可存储为txt、csv(适合表格数据)或json(适合结构化数据)文件。若需存储大量数据并执行复杂查询,可选择关系型(如MySQL)或非关系型(如MongoDB)数据库。以MySQL为例,需安装数据库和Python的pymysql库,创建数据库和表,然后编写Python代码进行数据操作。选择存储方式应考虑数据类型、数量及后续处理需求。
372 1

热门文章

最新文章