带你读《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

相关文章
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(4)
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(4)
|
IDE 开发工具
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(2)
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(2)
|
IDE 编译器 API
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(1)
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(1)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(4)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(4)
106 0
|
算法
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(3)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(3)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(5)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(5)
108 1
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(6)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(6)
|
网络协议
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(2)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(2)
130 1
|
SQL 缓存 JSON
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(1)
带你读《2022技术人的百宝黑皮书》——性能优化之接口优化(1)
159 1
|
算法 API
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(5)
带你读《2022技术人的百宝黑皮书》——stream的实用方法和注意事项(5)