美文网首页Java 杂谈JAVA_Spring
Java8 Three---- Stream Collector

Java8 Three---- Stream Collector

作者: kason_zhang | 来源:发表于2018-07-03 17:00 被阅读4次

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 是结果类型

相关文章

网友评论

    本文标题:Java8 Three---- Stream Collector

    本文链接:https://www.haomeiwen.com/subject/fmpluftx.html