Java实现List分组的常见方法详解
作者:悟能不能悟
这篇文章主要为大家详细介绍了使用Java实现List分组的几个常见方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
在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);6.选择建议
- Java 8+:优先使用
Stream API+Collectors.groupingBy(),代码简洁高效 - 复杂分组:使用多级分组或自定义分组逻辑
- 并行处理:考虑使用并行流
parallelStream() - 性能考虑:大数据量时注意选择合适的 Map 实现(如 LinkedHashMap 保持顺序)
这些方法可以根据具体需求灵活选择和使用。
到此这篇关于Java实现List分组的常见方法详解的文章就介绍到这了,更多相关Java List分组内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
