【问题标题】:Counting occurences of chars in string with stream用流计算字符串中字符的出现次数
【发布时间】:2020-04-04 03:50:58
【问题描述】:

我正在尝试理解 Java 中的流数据流。我的任务是将每个字母出现在字符串列表中

List<String> words = Arrays.asList("Welcome", "to", "the", "java", "world");

进入

Map<String, Long>

使用单线流。

我知道,首先我们可以从列表中流式传输每个单词,然后我需要将其分成字符,然后将每个字符作为键并将其出现次数计为值,最后返回整个地图。

理解起来很复杂。有人可以向我解释一下怎么做吗?

【问题讨论】:

    标签: java lambda java-stream


    【解决方案1】:

    您需要知道的是flatMap 是您可以用来将字符串转换为单个字符的函数。常规的map 函数只是将每个流元素转换为不同的元素,flatMap 将每个元素转换为元素的,然后将这些流连接在一起。

    String转换为字符流的函数是String.chars

    当您想从流中构建新集合时,通常会使用收集器。使用函数Collectors.groupingBy,您可以生成一个收集器,该收集器将创建一个Map,给定两个函数,一个为每个流值生成键,另一个生成值。有一个变体可以让您将另一个收集器作为第二个参数而不是函数传递;试试Collectors.counting

    【讨论】:

      【解决方案2】:

      正如 Willis 指出的那样,可以使用 flatMapgroupingBy 收集器来完成。但是,预期的输出类型应该是Map&lt;Character, Long&gt; fo,如下所示:

      Map<Character, Long> charFrequency = words.stream() //Stream<String>
              .flatMap(a -> a.chars().mapToObj(c -> (char) c)) // Stream<Character>
              .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
      

      【讨论】:

      • 你是对的。也可以在关键功能中进行这种转换。
      • 此代码因大多数字符而失败。示例:List&lt;String&gt; words = Arrays.asList( "?", "Welcome", "to", "the", "java", "world" ); 结果:{a=2, c=1, d=1, e=3, h=1, j=1, ?=1, l=2, m=1, o=3, r =1, t=2, v=1, w=1, W=1, ?=1} 如run live on IdeOne.com 所见。
      【解决方案3】:

      使用flatMapToInt 比使用flatMap(a -&gt; a.chars().mapToObj(c -&gt; (char) c)) 更具可读性

      words.stream()
                  .flatMapToInt(String::chars) //IntStream
                  .mapToObj(c -> (char) c)     //Stream<Character>
                  .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      猜你喜欢
      • 2014-04-24
      • 2020-02-21
      • 2012-02-12
      • 2023-02-04
      • 2020-05-06
      • 2010-10-27
      相关资源
      最近更新 更多