【问题标题】:Java List<String> to Map<String, Integer> convertionJava List<String> 到 Map<String, Integer> 的转换
【发布时间】:2017-07-18 03:13:08
【问题描述】:

我想在 java 8 中将 Map &lt;String, Integer&gt;List&lt;String&gt; 转换成这样的:

Map<String, Integer> namesMap = names.stream().collect(Collectors.toMap(name -> name, 0));

因为我有一个字符串列表,我想创建一个 Map,其中键是列表的字符串,值是整数(零)。

我的目标是计算字符串列表的元素(稍后在我的代码中)。

我知道以“旧”方式转换它很容易;

Map<String,Integer> namesMap = new HasMap<>();
for(String str: names) {
  map1.put(str, 0);
}

但我想知道还有 Java 8 解决方案。

【问题讨论】:

  • 只需将 0 更改为 name -&gt; 0: Map&lt;String, Integer&gt; namesMap = names.stream().collect(Collectors.toMap(name -&gt; name, name -&gt; 0)); 但如果您有重复,这将失败。如果您想计算出现次数,请首先正确操作:Map&lt;String, Long&gt; namesMap = names.stream().collect(Collectors.groupingBy(name -&gt; name, Collectors.counting())); 而不是name -&gt; name,您也可以使用Function.identity()
  • 哦,它正在工作,谢谢! :)

标签: java java-8 java-stream


【解决方案1】:

如前所述,Collectors.toMap 的参数必须是函数,因此您必须将0 更改为name -&gt; 0(您可以使用任何其他参数名称来代替name)。

但是请注意,如果names 中有重复项,这将失败,因为这将导致结果映射中的键重复。要解决此问题,您可以先通过 Stream.distinct 管道传输流:

Map<String, Integer> namesMap = names.stream().distinct()
                                     .collect(Collectors.toMap(s -> s, s -> 0));

或者根本不初始化这些默认值,而是使用getOrDefaultcomputeIfAbsent

int x = namesMap.getOrDefault(someName, 0);
int y = namesMap.computeIfAbsent(someName, s -> 0);

或者,如果你想得到名字的数量,你可以使用Collectors.groupingByCollectors.counting

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

【讨论】:

    【解决方案2】:

    toMap 收集器接收两个映射器 - 一个用于键,一个用于值。键映射器可以只返回列表中的值(即,像您目前拥有的那样name -&gt; name,或者只使用内置的Function.Identity)。值映射器应该只为任何键返回 0 的硬编码值:

    namesMap = 
        names.stream().collect(Collectors.toMap(Function.identity(), name -> 0));
    

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2022-09-30
      • 1970-01-01
      • 2018-05-08
      • 2017-01-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多