java - 计算 Stream 的元素

标签 java count java-8 java-stream collectors

我想计算流中的不同元素,想知道为什么

Stream<String> stream = Stream.of("a", "b", "a", "c", "c", "a", "a", "d");
Map<String, Integer> counter1 = stream.collect(Collectors.toMap(s -> s, 1, Integer::sum));

没用。 Eclipse 告诉我

The method toMap(Function, Function, BinaryOperator) in the type Collectors is not applicable for the arguments (( s) -> {}, int, Integer::sum)

顺便说一下,我知道那个解决方案:

Map<String, Long> counter2 = stream.collect(Collectors.groupingBy(s -> s, Collectors.counting()));

所以我有两个问题:

  1. 我的第一种方法有什么错误?
  2. 您将如何实现这样的计数器?

编辑:我自己解决了第一个问题:

Map<String, Integer> counter1 = stream.collect(Collectors.toMap(s -> s, s -> 1, Integer::sum)); 

Java 需要一个函数作为第二个参数。

最佳答案

确实有几种方法可以做到。你没有提到的是 .collect(groupingBy(x -> x, summingInt(x -> 1)));

性能上存在一些差异。

如果每个桶中的对象很少,方法 1 将达到最佳效果。在每个桶只有 1 个对象的理想情况下,您最终会立即得到最终映射,而无需修改条目。在有大量重复对象的最坏情况下,它将不得不进行大量装箱/拆箱操作。

方法 #2 依赖于 counting() 收集器,它没有具体指定应该如何进行计数。当前的实现转发到 reducing 但这可能会改变。

summingInt 方法将在 int 而不是 Integer 中累积计数,因此不需要任何装箱/拆箱。如果对象重复非常多的次数,它将处于最佳状态。

至于选择哪一个,最好编码清楚,必要时优化。对我来说,groupingBy(x->x, counting()) 最清楚地表达了意图,所以这是我喜欢的。

关于java - 计算 Stream 的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30451284/

相关文章:

java - 将对象列表转换为 <String,Map<String,Integer>> java8 流的映射

java - Wildfly 服务器、Maven、RestEasy(java.lang.ClassNotFoundException : org. jboss.resteasy.core.ResourceMethod)

MySQL 两表内连接和计数

java - 如何检查 Codenvy 生成的 java WAR 文件?

Javascript/JQuery : How do I count the words separated with a comma?

javascript - jQuery/JS - 在 DIV 中计算结果

java - Stream.max() 如何处理相等性?

java - 使用 Java 8 在列表中仅查找重复的字符串属性

java - SpringBoot 2 元素未绑定(bind)

java - Preon 枚举解释和映射