Collectors.counting()
Long collect = menu.stream().collect(Collectors.counting()); // 等同于menu.stream().count()
Collectors.maxBy() Collectors.minBy()
Optional<Dish> collect1 = menu.stream().collect(Collectors.maxBy(Comparator.comparing(Dish::getCalories)));
Optional<Dish> collect2 = menu.stream().max(Comparator.comparing(Dish::getCalories));
求和Collectors .summingInt
Integer collect3 = menu.stream().collect(Collectors.summingInt(Dish::getCalories));
System.out.println(collect3);
joining strings
将多个string合并成一个string
String collect4 = menu.stream().map(Dish::getName).collect(Collectors.joining());
String collect5 = menu.stream().map(Dish::getName).collect(Collectors.joining(","));
String collect6 = menu.stream().map(Dish::getName).collect(Collectors.joining(",","prefix","suffic"));
System.out.println(collect4);
System.out.println(collect5);
System.out.println(collect6);
返回的结果:
porkbeefchickenfrench friesriceseason fruitpizzaprawnssalmon
pork,beef,chicken,french fries,rice,season fruit,pizza,prawns,salmon
prefixpork,beef,chicken,french fries,rice,season fruit,pizza,prawns,salmonsuffic
Collectors.reducing计算和
Integer collect7 = menu.stream().collect(Collectors.reducing(0, Dish::getCalories, (x, y) -> x + y));
第一个参数就是起始值
第二个参数是把Dish转换成数字Int值
第三个参数是递归的累加函数
grouping
// 按Dish的Type分类
Map<Dish.Type, List<Dish>> collect7 = menu.stream().collect(Collectors.groupingBy(Dish::getType));
collect7.forEach((k,v) -> {
System.out.println(" key " + k);
v.forEach(System.out::println);
});
Map<CaloriesLevel, List<Dish>> collect8 = menu.stream().collect(Collectors.groupingBy(dish -> {
if (dish.getCalories() < 400) {
return CaloriesLevel.GOOD;
} else if (dish.getCalories() < 700) {
return CaloriesLevel.MIDDLE;
} else {
return CaloriesLevel.BAD;
}
}));
System.out.println(collect8);
输出: {GOOD=[rice, season fruit, prawns], BAD=[pork, beef], MIDDLE=[chicken, french fries, pizza, salmon]}
两次groupBy
Map<Dish.Type, Map<CaloriesLevel, List<Dish>>> collect9 = menu.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.groupingBy(dish -> {
if (dish.getCalories() < 400) {
return CaloriesLevel.GOOD;
} else if (dish.getCalories() < 700) {
return CaloriesLevel.MIDDLE;
} else {
return CaloriesLevel.BAD;
}
})));
System.out.println(collect9);
Map<CaloriesLevel, Map<Dish.Type, List<Dish>>> collect10 = menu.stream().collect(Collectors.groupingBy(dish -> {
if (dish.getCalories() < 400) {
return CaloriesLevel.GOOD;
} else if (dish.getCalories() < 700) {
return CaloriesLevel.MIDDLE;
} else {
return CaloriesLevel.BAD;
}
}, Collectors.groupingBy(Dish::getType)));
System.out.println(collect10);
输出结果
{MEAT={BAD=[pork, beef], MIDDLE=[chicken]}, FISH={GOOD=[prawns], MIDDLE=[salmon]}, OTHER={GOOD=[rice, season fruit], MIDDLE=[french fries, pizza]}}
{GOOD={FISH=[prawns], OTHER=[rice, season fruit]}, BAD={MEAT=[pork, beef]}, MIDDLE={MEAT=[chicken], FISH=[salmon], OTHER=[french fries, pizza]}}
Collecting data in subgroups 即在groupBy传递的参数里面不仅仅可以传递Collectors.groupBy可以传递Collectors.otherMethod
Map<Dish.Type, Long> collect11 = menu.stream().collect(Collectors.groupingBy(Dish::getType, Collectors.counting()));
System.out.println(collect11);
输出:
{MEAT=3, FISH=2, OTHER=4}
Partitioning 特殊的分组, 分成两组(true组, false组)
Map<Boolean, List<Dish>> collect12 = menu.stream().collect(Collectors.partitioningBy(Dish::isVegetarian));
System.out.println(collect12);
List<Dish> dishes = collect12.get(true);
System.out.println(dishes);
结果:
{false=[pork, beef, chicken, prawns, salmon], true=[french fries, rice, season fruit, pizza]}
[french fries, rice, season fruit, pizza]
这种分组操作,完全可以通过filter操作结合collect来完成, 比如上面即等价于:
List<Dish> collect13 = menu.stream().filter(Dish::isVegetarian).collect(Collectors.toList());
System.out.println(collect13);
partitioningBy将和groupingBy类似,As you’ve seen, like the groupingBy collector, the partitioningBy collector can be used in combination with other collectors. In particular it could be used with a second partitioningBy collector to achieve a multilevel partitioning.
自定义Collector接口
public interface Collector<T, A, R> {
Supplier<A> supplier(); //Making a new result container: the supplier method
BiConsumer<A, T> accumulator();// Adding an element to a result container
Function<A, R> finisher();//Applying the final transformation to the result container
BinaryOperator<A> combiner();//Merging two result containers. allows a parallel reduction of the stream
Set<Characteristics> characteristics();
}
T Stream元素的类型, A 则是累加的类型, R 是结果类型
网友评论