Java 8 中的 Group By

2025年8月18日 | 4 分钟阅读

Java 8 中的 Collectors.groupingBy() 方法现在允许开发人员直接执行 GROUP BY 操作。GROUP BY 是一种 SQL 聚合操作,非常有用。它允许您根据指定的标准对记录进行分类。在 Java 中,如何进行 group by?例如,如果您有一个人员列表,如何按城市组织他们?是去伦敦、巴黎还是东京?我们可以用一个 for 循环来完成,检查每个人,并将他们放入具有相同城市的 HashMap 列表中,但在 Java 8 中,您不必那样费力地解决;您有一个更简单的选择。要实现这一点,您可以使用 Stream 和 Collector 提供的 groupingBy() 方法。

它具有重要的价值,因为它是最常见的聚合数据方式之一,特别是与 groupingBy() 的不同重载版本结合使用时,它还可以让您通过利用并发 Collector 来同时对项目进行分组。

如何在 Java 8 中分组对象?

示例

这是一个 Java 8 及更早版本用于根据特征分组对象的示例程序。首先,我们将看看如何在 Java 8 之前的环境中实现这一点,然后我们将看一个 Java 8 的 group 示例。通过查看这两种技术,很明显 Java 8 使您的工作变得更容易。

要在 Java SE 6 或 7 中从列表中构建一组对象,您必须遍历列表,检查每个元素,并将它们放入自己的列表中。为了存储这些分组,您还需要一个 Map。当您获取新组的第一个项时,您会创建一个列表并将其添加到列表中,但如果该组已存在于 Map 中,您只需获取它并将您的元素添加到其中。

代码并不难写,但需要 5 到 6 行,并且您必须到处检查 null 引用以避免 NullPointerException。在 Java 8 中,您只需一行代码即可从列表中检索流并使用 Collector 对它们进行分组。这就像将分组条件传递给 collector 一样简单,然后就完成了。

只需修改分组条件,您就可以创建多个组。要在旧版本中建立不同标准的组,您必须编写相同的 5 到 6 行代码。

您甚至可以使用新的 Stream API 来执行聚合函数,如 sum()、count()、max() 和 min(),这些函数可以在特定组中执行,正如我在之前的 stream 示例中所展示的那样。毕竟,单个组只是一个对象列表,您可以通过调用 stream() 方法来访问它们上的流。换句话说,您现在可以在 Java 中执行类似 SQL 的分组,而无需使用循环。

Java 程序分组对象

GroupByDemo.java

输出

Employees grouped by cities before Java 8 : {Delhi=[Dipak(Delhi,21), Sumit(Delhi,21), Karan(Delhi,23)], Banglore=[Rajesh(Banglore,23), Niraj(Banglore,31)], Udaipur=[Mona(Udaipur,23)]}
Employees grouped by cities in Java 8: {Delhi=[Dipak(Delhi,21), Sumit(Delhi,21), Karan(Delhi,23)], Banglore=[Rajesh(Banglore,23), Niraj(Banglore,31)], Udaipur=[Mona(Udaipur,23)]}
Employees grouped by age in Java 8: {21=[Dipak(Delhi,21), Sumit(Delhi,21)], 23=[Karan(Delhi,23), Mona(Udaipur,23), Rajesh(Banglore,23)], 31=[Niraj(Banglore,31)]}

在上面的示例中,我们按城市对 Employee 对象列表进行分类。我们的列表中有三名来自德里、两名来自乌代浦和一名来自班加罗尔的员工。按城市排序后,您可以看到他们每个人都有自己的列表;Udaipur 列表中有 1 名员工,Delhi 列表中有 3 名,Bangalore 列表中有 2 名。Java 7 和 Java 8 示例形成的组是相同的。

之后,它根据年龄分为三组,正如所示,我们有三个年龄组,分别为 21、23 和 31。