【问题标题】:Counting elements of a Stream计算 Stream 的元素
【发布时间】:2015-08-07 16:45:56
【问题描述】:

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

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 告诉我

类型Collectors中的toMap(Function, Function, BinaryOperator)方法不适用于参数((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 期望一个函数作为第二个参数。

【问题讨论】:

  • 如果您自己解决了问题,只需写一个答案而不是编辑问题。
  • @TagirValeev 这只是第一部分。答案不应该回答完整的问题吗?我也希望人们不再担心告诉我我做错了什么。
  • @NitinDandriyal 这正是第二种方法。
  • 如果您需要Map&lt;String, Integer&gt;,您可以使用.collect(groupingBy(s -&gt; s, summingInt(s -&gt; 1)));,尽管counting() 方法更具可读性。

标签: java count java-8 java-stream collectors


【解决方案1】:

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

在性能上有一些差异。

如果每个存储桶的对象很少,方法 #1 将处于最佳状态。在每个桶只有 1 个对象的理想情况下,您可以立即获得最终映射,而无需修改条目。在有大量重复对象的最坏情况下,它将不得不进行大量装箱/拆箱。

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

summingInt 方法将在int 而不是Integer 中累积计数,因此不需要任何装箱/拆箱。如果对象重复很多次,那将是最好的。

至于选择哪一个,最好把代码写清楚,必要时再优化。对我来说,groupingBy(x-&gt;x, counting()) 表达的意图最清楚,所以这是我喜欢的。

【讨论】:

    【解决方案2】:

    如果您不使用并行流,以下应该可以工作:

    final int[] counter = {0};
    stream.peek(s -> counter[0]++);
    

    【讨论】:

      【解决方案3】:
          private Collector<CustomObject.class, int[], Integer> customIntegerCountingCollector() {
          return Collector.of(
              () -> new int[1],
              (result, ) -> result[0] += 1,
              (result1, result2) -> {
                  result1[0] += result2[0];
                  return result1;
              },
              total -> Integer.valueOf(total[0])
          );
      }
      

      灵感来自:https://www.deadcoderising.com/2017-03-07-java-8-creating-a-custom-collector-for-your-stream/

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-03
        • 2017-08-23
        • 2016-08-16
        • 1970-01-01
        相关资源
        最近更新 更多