1. 概述
在这个简短的教程中,我们将了解如何将相等的对象分组并计算它们在Java中的出现次数。我们将在Java中使用groupingBy()收集器。
2. 使用Collectors.groupingBy()计算出现次数
Collectors.groupingBy()提供类似于SQL中的GROUP BY子句的功能。我们可以使用它按任何属性对对象进行分组并将结果存储在Map中。
例如,让我们考虑一个场景,我们需要在流中对相等的String进行分组并计算它们的出现次数:
List<String> list = new ArrayList<>(Arrays.asList("Foo", "Bar", "Bar", "Bar", "Foo"));
我们可以将相等的字符串分组,在本例中为“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"));
让我们分解上面的代码片段:
- Map<String, Long> result:这是输出结果Map,它将分组元素存储为键并将它们的出现次数计为值
- list.stream():我们将列表元素转换为Java Stream以声明方式处理集合
- Collectors.groupingBy():这是Collectors类的方法,用于按某些属性对对象进行分组并将结果存储在Map实例中
- Function.identity():它是Java中的函数式接口;identity方法返回一个始终返回其输入参数的函数
- Collectors.counting():此Collectors类方法将流中传递的元素数作为参数进行计数
我们可以使用Collectors.groupingByConcurrent()而不是Collectors.groupingBy()。它还对输入流元素执行分组操作。该方法将结果收集到ConcurrentMap中,从而提高效率。
例如,对于输入列表:
List<String> list = new ArrayList<>(Arrays.asList("Adam", "Bill", "Jack", "Joe", "Ian"));
我们可以使用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. 总结
在本文中,我们介绍了Collector.groupingBy()对相等对象进行分组的用法。
与往常一样,本教程的完整源代码可在GitHub上获得。
Show Disqus Comments
Post Directory
扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章