Java8 用流收集数据之归约汇总

在这里插入图片描述

规约汇总

最大值 (max)・最小值 (min)

# 询卡路里最高的菜
Dish dish1 = Dish.menu.stream().max(Comparator.comparingInt(Dish::getCalories)).get();
Dish dish2 = Dish.menu.stream().max(Comparator.comparingLong(Dish::getCalories)).get();
Dish dish3 = Dish.menu.stream().max(Comparator.comparingDouble(Dish::getCalories)).get();

# 查询最高的卡路里
int    max = Dish.menu.stream().mapToInt(Dish::getCalories).max().getAsInt();
long   max = Dish.menu.stream().mapToLong(Dish::getCalories).max().getAsLong();
double max = Dish.menu.stream().mapToDouble(Dish::getCalories).max().getAsDouble();

# 仅了解即可:Collectors.reducing
Dish dish = menu.stream().collect(Collectors.reducing(BinaryOperator.maxBy(Comparator.comparingInt(Dish::getCalories)))).get();

在这里插入图片描述

统计总数 (count)

# count()
long count = Dish.menu.stream().count();

# 仅了解即可:Collectors.counting()
long count = Dish.menu.stream().collect(Collectors.counting());

在这里插入图片描述

统计求和 (summingInt・summingLong・summingDouble・sum)

# 获取所有菜的卡路里之和
int    total1   = Dish.menu.stream().mapToInt(Dish::getCalories).sum();
long   total2   = Dish.menu.stream().mapToLong(Dish::getCalories).sum();
double total3   = Dish.menu.stream().mapToDouble(Dish::getCalories).sum();

# 1. 如果流是空的,sum默认返回0
# 2. 求前3项和
int sum1 = Dish.menu.stream().mapToInt(Dish::getCalories).limit(3).sum(); 		  // 1+2+2=5 求前3项和
# 3. 求3到5项的和
int sum2 = Dish.menu.stream().mapToInt(Dish::getCalories).skip(2).limit(3).sum(); // 2+4+4=10 求3到5项的加和

# 仅了解即可:Collectors.summingInt
int    total1 	= Dish.menu.stream().collect(Collectors.summingInt(Dish::getCalories));
long   total2 	= Dish.menu.stream().collect(Collectors.summingLong(Dish::getCalories));
double total3   = Dish.menu.stream().collect(Collectors.summingDouble(Dish::getCalories));

在这里插入图片描述

平均值 (averagingInt・averagingLong・averagingInt・average)

# 获取所有菜的卡路里的平均值
double avg1 = Dish.menu.stream().mapToInt(Dish::getCalories).average().getAsDouble();
double avg2 = Dish.menu.stream().mapToLong(Dish::getCalories).average().getAsDouble();
double avg3 = Dish.menu.stream().mapToDouble(Dish::getCalories).average().getAsDouble();

# 仅了解即可:Collectors.averagingInt
double avg = Dish.menu.stream().collect(Collectors.averagingInt(Dish::getCalories));
double avg = Dish.menu.stream().collect(Collectors.averagingLong(Dish::getCalories));
double avg = Dish.menu.stream().collect(Collectors.averagingInt(Dish::getCalories));

在这里插入图片描述

统计梗概 (summarizingInt・summarizingLong・summarizingDouble・summaryStatistics)

# IntSummaryStatistics{count=9, sum=4300, min=120,average=477.777778, max=800}
# 获取所有菜的Statistic
IntSummaryStatistics    statistics1 = Dish.menu.stream().mapToInt(Dish::getCalories).summaryStatistics();
LongSummaryStatistics   statistics2 = Dish.menu.stream().mapToLong(Dish::getCalories).summaryStatistics();
DoubleSummaryStatistics statistics3 = Dish.menu.stream().mapToDouble(Dish::getCalories).summaryStatistics();

# 仅了解即可:Collectors.summarizingInt
IntSummaryStatistics    statistics  = Dish.menu.stream().collect(Collectors.summarizingInt(Dish::getCalories));
LongSummaryStatistics   statistics  = Dish.menu.stream().collect(Collectors.summarizingLong(Dish::getCalories));
DoubleSummaryStatistics statistics  = Dish.menu.stream().collect(Collectors.summarizingDouble(Dish::getCalories));

在这里插入图片描述

连接字符串 (joining)

joining在内部使用了StringBuilder来把生成的字符串逐个追加起来;

String shortMenu = menu.stream().map(Dish::getName).collect(Collectors.joining());
// 结果:porkbeefchickenfrench friesriceseason fruitpizzaprawnssalmon

String shortMenu = menu.stream().map(Dish::getName).collect(Collectors.joining(", "));
// 结果:pork, beef, chicken, french fries, rice, season fruit, pizza, prawns, salmon

在这里插入图片描述

广义的归约(reducing)

上文所有收集器,都是一个可以用reducing工厂方法定义的归约过程的特殊情况而已。

# 计算菜单总热量的归约过程
int totalCalories = menu.stream().collect(Collectors.reducing(0, Dish::getCalories, (i, j) -> i + j));
int totalCalories = menu.stream().collect(Collectors.reducing(0, Dish::getCalories, Integer::sum));
int totalCalories = menu.stream().map(Dish::getCalories).reduce(Integer::sum).get();
int totalCalories = menu.stream().mapToInt(Dish::getCalories).sum();
# 我们更倾向于最后一个解决方案,因为它最简明,也很可能最易读。同时,它也是性能最好的一个,因为IntStream可以让我们避免自动拆箱操作。

# 用reducing连接字符串
String shortMenu = menu.stream().collect(Collectors.reducing("", Dish::getName, (s1, s2) -> s1 + s2 ));
String shortMenu = menu.stream().map(Dish::getName).collect(Collectors.reducing((s1, s2) -> s1 + s2)).get();
String shortMenu = menu.stream().map(Dish::getName).collect(Collectors.joining());
# 就实际应用而言,不管是从可读性还是性能方面考虑,我们始终建议使用joining收集器。

-----------------------------------------------------------------------------读书笔记摘自 书名:Java 8实战 作者:[英] Raoul-Gabriel Urma [意] Mario Fusco [英] Alan M

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值