java list怎么进行group

在Java中,对List进行分组有多种方法,以下是常见的几种方式:

1. 使用 Stream API (Java 8+ 推荐)

1.1 按属性分组

复制代码
// 按对象属性分组
List<Person> people = Arrays.asList(
    new Person("Alice", "IT"),
    new Person("Bob", "HR"),
    new Person("Charlie", "IT")
);

Map<String, List<Person>> byDept = people.stream()
    .collect(Collectors.groupingBy(Person::getDepartment));

// 复杂分组:按多个条件分组
Map<String, Map<Integer, List<Person>>> byDeptAndAge = people.stream()
    .collect(Collectors.groupingBy(
        Person::getDepartment,
        Collectors.groupingBy(Person::getAge)
    ));

1.2 分组后处理

复制代码
// 分组并计数
Map<String, Long> countByDept = people.stream()
    .collect(Collectors.groupingBy(
        Person::getDepartment,
        Collectors.counting()
    ));

// 分组并求和
Map<String, Integer> sumByDept = people.stream()
    .collect(Collectors.groupingBy(
        Person::getDepartment,
        Collectors.summingInt(Person::getSalary)
    ));

// 分组后获取最大/最小值
Map<String, Optional<Person>> maxByDept = people.stream()
    .collect(Collectors.groupingBy(
        Person::getDepartment,
        Collectors.maxBy(Comparator.comparing(Person::getSalary))
    ));

2. 使用传统循环

复制代码
Map<String, List<Person>> byDept = new HashMap<>();

for (Person person : people) {
    String dept = person.getDepartment();
    byDept.computeIfAbsent(dept, k -> new ArrayList<>())
          .add(person);
}

3. 使用第三方库

3.1 Apache Commons Collections

复制代码
// 添加依赖
// implementation 'org.apache.commons:commons-collections4:4.4'

MultiValuedMap<String, Person> byDept = new ArrayListValuedHashMap<>();
for (Person person : people) {
    byDept.put(person.getDepartment(), person);
}

3.2 Google Guava

复制代码
// 添加依赖
// implementation 'com.google.guava:guava:31.1-jre'

Multimap<String, Person> byDept = ArrayListMultimap.create();
for (Person person : people) {
    byDept.put(person.getDepartment(), person);
}

// 或者使用流式方式
ImmutableListMultimap<String, Person> grouped = Multimaps.index(
    people, Person::getDepartment
);

4. 完整示例

复制代码
import java.util.*;
import java.util.stream.Collectors;

class Person {
    private String name;
    private String department;
    private int age;
    private int salary;
    
    // 构造方法、getter、setter
    
    public static void main(String[] args) {
        List<Person> people = Arrays.asList(
            new Person("Alice", "IT", 25, 5000),
            new Person("Bob", "HR", 30, 4500),
            new Person("Charlie", "IT", 28, 5500),
            new Person("David", "HR", 35, 4800)
        );
        
        // 1. 按部门分组
        Map<String, List<Person>> byDept = people.stream()
            .collect(Collectors.groupingBy(Person::getDepartment));
        
        // 2. 按部门统计平均工资
        Map<String, Double> avgSalaryByDept = people.stream()
            .collect(Collectors.groupingBy(
                Person::getDepartment,
                Collectors.averagingDouble(Person::getSalary)
            ));
        
        // 3. 按年龄段分组
        Map<String, List<Person>> byAgeGroup = people.stream()
            .collect(Collectors.groupingBy(p -> {
                if (p.getAge() < 30) return "青年";
                else if (p.getAge() < 40) return "中年";
                else return "资深";
            }));
    }
}

5. 自定义分组逻辑

复制代码
// 自定义分组器
Collector<Person, ?, Map<String, List<Person>>> customGrouping = 
    Collector.of(
        HashMap::new,  // 供应者
        (map, person) -> {  // 累加器
            String key = person.getDepartment() + "-" + 
                        (person.getAge() / 10 * 10);  // 按10岁分段
            map.computeIfAbsent(key, k -> new ArrayList<>())
               .add(person);
        },
        (map1, map2) -> {  // 合并器(用于并行流)
            map2.forEach((key, value) -> 
                map1.merge(key, value, (list1, list2) -> {
                    list1.addAll(list2);
                    return list1;
                })
            );
            return map1;
        }
    );

Map<String, List<Person>> customGrouped = people.stream()
    .collect(customGrouping);

选择建议:

  1. Java 8+ :优先使用 Stream API+ Collectors.groupingBy(),代码简洁高效

  2. 复杂分组:使用多级分组或自定义分组逻辑

  3. 并行处理 :考虑使用并行流 parallelStream()

  4. 性能考虑:大数据量时注意选择合适的 Map 实现(如 LinkedHashMap 保持顺序)

这些方法可以根据具体需求灵活选择和使用。

相关推荐
laufing几秒前
flask_restx 创建restful api
python·flask·restful
一勺菠萝丶4 分钟前
PDF24 转图片出现“中间横线”的根本原因与终极解决方案(DPI 原理详解)
java
姓蔡小朋友8 分钟前
Unsafe类
java
一只专注api接口开发的技术猿22 分钟前
如何处理淘宝 API 的请求限流与数据缓存策略
java·大数据·开发语言·数据库·spring
荒诞硬汉23 分钟前
对象数组.
java·数据结构
期待のcode24 分钟前
Java虚拟机的非堆内存
java·开发语言·jvm
黎雁·泠崖25 分钟前
Java入门篇之吃透基础语法(二):变量全解析(进制+数据类型+键盘录入)
java·开发语言·intellij-idea·intellij idea
仙俊红28 分钟前
LeetCode484周赛T4
java