目录
- 规约汇总
- 最大值 (max)・最小值 (min)
- 统计总数 (count)
- 统计求和 (summingInt・summingLong・summingDouble・sum)
- 平均值 (averagingInt・averagingLong・averagingInt・average)
- 统计梗概 (summarizingInt・summarizingLong・summarizingDouble・summaryStatistics)
- 连接字符串 (joining)
- 广义的归约(reducing)
规约汇总
最大值 (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