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 保持顺序)

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

相关推荐
二哈赛车手4 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
wj3055853784 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
栗子~~5 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
星寂樱易李5 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
YDS8295 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
qingfeng154155 小时前
企业微信机器人开发:如何实现自动化与智能运营?
人工智能·python·机器人·自动化·企业微信
未若君雅裁6 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
AI人工智能+电脑小能手7 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记7 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring