Java8 stream 中利用 groupingBy 进行多字段分组求和

Java8的groupingBy实现集合的分组,类似Mysql的group by分组功能,注意得到的是一个map

对集合按照单个属性分组

case1:

List items =
        Arrays.asList("apple", "apple", "banana",
                "apple", "orange", "banana", "papaya");
// 分组
Map> result1 = items.stream().collect(
        Collectors.groupingBy(
                Function.identity()
        )
);
//{papaya=[papaya], orange=[orange], banana=[banana, banana], apple=[apple, apple, apple]}
System.out.println(result1);
// 分组计数
Map result2 = items.stream().collect(
        Collectors.groupingBy(
                Function.identity(), Collectors.counting()
        )
);
// {papaya=1, orange=1, banana=2, apple=3}
System.out.println(result2);
Map finalMap = new LinkedHashMap<>();
//分组, 计数和排序
result2.entrySet().stream()
        .sorted(Map.Entry.comparingByValue().reversed())
        .forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));
// {apple=3, banana=2, papaya=1, orange=1}
System.out.println(finalMap);

case2:

User user1 = new User("zhangsan", "beijing", 10);
User user2 = new User("zhangsan", "beijing", 20);
User user3 = new User("lisi", "shanghai", 30);
List list = new ArrayList();
list.add(user1);
list.add(user2);
list.add(user3);
Map> collect = list.stream()
        .collect(
                Collectors.groupingBy(
                        User::getName/*, Collectors.counting()*/
                )
        );
//{lisi=[User{age=30, name='lisi', address='shanghai'}], 
// zhangsan=[User{age=10, name='zhangsan', address='beijing'}, User{age=20, name='zhangsan', address='beijing'}]}
System.out.println(collect);

集合按照多个属性分组

1.多个属性拼接出一个组合属性

public static void main(String[] args) {
    User user1 = new User("zhangsan", "beijing", 10);
    User user2 = new User("zhangsan", "beijing", 20);
    User user3 = new User("lisi", "shanghai", 30);
    List list = new ArrayList();
    list.add(user1);
    list.add(user2);
    list.add(user3);
    Map> collect = list.stream().collect(Collectors.groupingBy(e -> fetchGroupKey(e)));
    //{zhangsan#beijing=[User{age=10, name='zhangsan', address='beijing'}, User{age=20, name='zhangsan', address='beijing'}], 
    // lisi#shanghai=[User{age=30, name='lisi', address='shanghai'}]}
    System.out.println(collect);
}
private static String fetchGroupKey(User user){
    return user.getName() +"#"+ user.getAddress();
}

2.嵌套调用groupBy

不过感觉这样把问题搞复杂了

User user1 = new User("zhangsan", "beijing", 10);
User user2 = new User("zhangsan", "beijing", 20);
User user3 = new User("lisi", "shanghai", 30);
List list = new ArrayList();
list.add(user1);
list.add(user2);
list.add(user3);
Map>> collect
        = list.stream().collect(
                Collectors.groupingBy(
                        User::getAddress, Collectors.groupingBy(User::getName)
                )
);
System.out.println(collect);

Ref:

https://stackoverflow.com/questions/28342814/group-by-multiple-field-names-in-java-8#

转载于:https://www.cnblogs.com/winner-0715/p/10246037.html

你可能感兴趣的:(Java8 stream 中利用 groupingBy 进行多字段分组求和)