Java 8 Stream: groupingBy with multiple Collectors

后端 未结 4 742
野性不改
野性不改 2020-12-15 08:20

I want to use a Java 8 Stream and Group by one classifier but have multiple Collector functions. So when grouping, for example the average and the sum of one field (or maybe

4条回答
  •  囚心锁ツ
    2020-12-15 08:56

    By using a map as an output type one could have a potentially infinite list of reducers each producing its own statistic and adding it to the map.

    public static  Map addMap(Map map, K k, V v) {
        Map mapout = new HashMap();
        mapout.putAll(map);
        mapout.put(k, v);
        return mapout;
    }
    

    ...

        List persons = new ArrayList<>();
        persons.add(new Person("Person One", 1, 18));
        persons.add(new Person("Person Two", 1, 20));
        persons.add(new Person("Person Three", 1, 30));
        persons.add(new Person("Person Four", 2, 30));
        persons.add(new Person("Person Five", 2, 29));
        persons.add(new Person("Person Six", 3, 18));
    
        List, Person, Map>> listOfReducers = new ArrayList<>();
    
        listOfReducers.add((m, p) -> addMap(m, "Count", Optional.ofNullable(m.get("Count")).orElse(0) + 1));
        listOfReducers.add((m, p) -> addMap(m, "Sum", Optional.ofNullable(m.get("Sum")).orElse(0) + p.i1));
    
        BiFunction, Person, Map> applyList
                = (mapin, p) -> {
                    Map mapout = mapin;
                    for (BiFunction, Person, Map> f : listOfReducers) {
                        mapout = f.apply(mapout, p);
                    }
                    return mapout;
                };
        BinaryOperator> combineMaps
                = (map1, map2) -> {
                    Map mapout = new HashMap<>();
                    mapout.putAll(map1);
                    mapout.putAll(map2);
                    return mapout;
                };
        Map map
                = persons
                .stream()
                .reduce(new HashMap(),
                        applyList, combineMaps);
        System.out.println("map = " + map);
    

    Produces :

    map = {Sum=10, Count=6}
    

提交回复
热议问题