
在 Java 开发中,对大量数据进行高效分组和统计分析是常见任务。本文探讨两种数据分组技术:HashMap 和 Java 8 的 groupingBy 与 reduce 方法,给出代码示例和应用场景分析

HashMap是Java中最基础且广泛使用的键值对容器之一,可用于手动实现数据分组。使用HashMap对对象按某个属性分组的示例:
import java.util.*;
public class HashMapGroupingExample {
public static void main(String[] args) {
List<Person> people = Arrays.asList(
new Person("Alice", "NY"),
new Person("Bob", "LA"),
new Person("Charlie", "NY"),
new Person("David", "LA")
);
// 创建一个空的HashMap用于存储分组结果
Map<String, List<Person>> groupedPeople = new HashMap<>();
for (Person person : people) {
String city = person.getCity();
if (!groupedPeople.containsKey(city)) {
groupedPeople.put(city, new ArrayList<>());
}
groupedPeople.get(city).add(person);
}
// 输出分组结果
for (Map.Entry<String, List<Person>> entry : groupedPeople.entrySet()) {
System.out.println("City: " + entry.getKey() + ", People: " + entry.getValue());
}
}
static class Person {
private String name;
private String city;
// 构造函数、getters & setters 省略
}
} // 输出分组结果
for (Map.Entry<String, List<Person>> entry : groupedPeople.entrySet()) {
System.out.println("City: " + entry.getKey() + ", People: " + entry.getValue());
}
}在 Java 中,Map接口是键值对数据结构,entrySet()返回集合视图。groupedPeople是Map<String, List<Person>>对象,代表分组结果。通过for-each循环遍历groupedPeople.entrySet(),每次迭代得到Map.Entry对象,entry.getKey()获键(城市名),entry.getValue()获值(人员列表),每次循环打印“City: 城市名, People: 人员列表”展示分组结果
Java 8 Stream API提供了Collectors.groupingBy()方法,使得数据分组操作更为简洁和直观:
import java.util.*;
import java.util.stream.Collectors;
public class StreamGroupingByExample {
public static void main(String[] args) {
List<Person> people = ...; // 同上
// 使用Stream API进行分组
Map<String, List<Person>> groupedPeople = people.stream()
.collect(Collectors.groupingBy(Person::getCity));
// 输出分组结果
for (Map.Entry<String, List<Person>> entry : groupedPeople.entrySet()) {
System.out.println("City: " + entry.getKey() + ", People: " + entry.getValue());
}
}
}
// 解释:
// `Collectors.groupingBy()`接收一个函数作为参数,该函数返回的是每个元素的分组键(这里为城市名)。除了分组,Stream API还提供reduce()方法进行更复杂的聚合计算。例如,我们可以计算每个城市的总人口数:
import java.util.*;
import java.util.stream.Collectors;
public class StreamReduceExample {
public static void main(String[] args) {
List<Person> people = ...; // 同上
// 使用groupingBy与reduce结合进行分组并统计人数
Map<String, Long> cityPopulation = people.stream()
.collect(Collectors.groupingBy(Person::getCity, Collectors.reducing(0L, p -> 1L, Long::sum)));
// 输出结果
for (Map.Entry<String, Long> entry : cityPopulation.entrySet()) {
System.out.println("City: " + entry.getKey() + ", Population: " + entry.getValue());
}
}
}
// 解释:
// 在此案例中,我们首先通过groupingBy分组,然后在收集器中使用reducing方法,初始值为0L, lambda表达式p -> 1L将每个人视为1单位的人口数,最后Long::sum用于累加这些人口数。原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。