1. Overview
1.概述
In this short tutorial, we’ll see how we can group equal objects and count their occurrences in Java. We’ll use the groupingBy() collector in Java.
在这个简短的教程中,我们将看到如何在Java中对相等的对象进行分组并计算其出现次数。我们将使用Java中的groupingBy() collector。
2. Count Occurrences using Collectors.groupingBy()
2.使用Collectors.groupingBy()计算出现次数
Collectors.groupingBy() provides functionality similar to the GROUP BY clause in SQL. We can use this to group objects by any attribute and store results in a Map.
Collectors.groupingBy()提供了类似于SQL中GROUP BY子句的功能。我们可以用它来按任何属性对对象进行分组,并将结果存储在一个Map中。
For instance, let’s consider a scenario where we need to group equal Strings in a stream and count their occurrences:
例如,让我们考虑这样一种情况:我们需要在一个流中对相等的Strings进行分组并计算它们的出现次数。
List<String> list = new ArrayList<>(Arrays.asList("Foo", "Bar", "Bar", "Bar", "Foo"));
We can group equal Strings, which in this case would be “Foo” and “Bar”. The result Map will store these Strings as keys. The values for these keys will be the count of occurrences. The value for “Foo” will be 2 and “Bar” will be 3:
我们可以将相等的字符串分组,在本例中是 “Foo “和 “Bar”。结果Map将存储这些字符串作为键。这些键的值将是出现的次数。Foo “的值是2,”Bar “的值是3。
Map<String, Long> result = list.stream()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Assert.assertEquals(new Long(2), result.get("Foo"));
Assert.assertEquals(new Long(3), result.get("Bar"));
Let’s decode the above code snippet:
让我们来解码上述代码片断。
- Map<String, Long> result – this is the output result Map that will store the grouped elements as keys and count their occurrences as values
- list.stream() – we convert the list elements into Java stream to process the collection in a declarative way
- Collectors.groupingBy() – this is the method of Collectors class to group objects by some property and store results in a Map instance
- Function.identity() – it is a functional interface in Java; the identity method returns a Function that always returns its input arguments
- Collectors.counting() – this Collectors class method counts the number of elements passed in the stream as a parameter
We could use Collectors.groupingByConcurrent() instead of Collectors.groupingBy(). It also performs group by operation on input stream elements. The method collects the results in ConcurrentMap, thus improving efficiency.
我们可以使用Collectors.groupingByConcurrent() 代替Collectors.groupingBy()。它也对输入流元素进行分组操作。该方法将结果收集在ConcurrentMap中,从而提高了效率。
For example, for the input list:
例如,对于输入列表。
List<String> list = new ArrayList<>(Arrays.asList("Adam", "Bill", "Jack", "Joe", "Ian"));
We can group equal length Strings using Collectors.groupingByConcurrent():
我们可以使用Collectors.groupingByConcurrent()将等长的字符串分组。
Map<Integer, Long> result = list.stream()
.collect(Collectors.groupingByConcurrent(String::length, Collectors.counting()));
Assert.assertEquals(new Long(2), result.get(3));
Assert.assertEquals(new Long(3), result.get(4));
3. Conclusion
3.结论
In this article, we covered the usage of Collector.groupingBy() to group the equal objects.
在这篇文章中,我们介绍了 Collector.groupingBy()的用法,将相等的对象分组。
And to wrap up, you’ll find the source code to this article over on GitHub.
作为总结,你可以在GitHub上找到本文的源代码。