如何使用流将列表转换为带有索引的地图 \- Java 8?

新手上路,请多包涵

我已经创建了计算字母表中每个字符的方法。我正在学习流(函数式编程)并尝试尽可能多地使用它们,但在这种情况下我不知道该怎么做:

 private Map<Character, Integer> numerateAlphabet(List<Character> alphabet) {
    Map<Character, Integer> m = new HashMap<>();
    for (int i = 0; i < alphabet.size(); i++)
        m.put(alphabet.get(i), i);
    return m;
}

那么,如何使用 Java 8 的流重写它呢?

原文由 Letfar 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 336
2 个回答

避免有状态的索引计数器,例如其他答案中提供的基于 AtomicInteger 的解决方案。如果流是并行的,它们将失败。相反,流过索引:

 IntStream.range(0, alphabet.size())
         .boxed()
         .collect(toMap(alphabet::get, i -> i));

上面假设传入列表不应该有重复的字符,因为它是一个字母表。如果您有重复元素的可能性,那么多个元素将映射到相同的键,然后您需要指定 合并功能。例如,您可以使用 (a,b) -> b(a,b) ->a 作为 toMap 方法的第三个参数。

原文由 Misha 发布,翻译遵循 CC BY-SA 3.0 许可协议

最好使用 Function.identity() 代替 i->i 因为根据 这个 问题的答案:

在当前的 JRE 实现中,Function.identity() 将始终返回相同的实例,而每次出现 identifier -> identifier 不仅会创建自己的实例,甚至还会有一个不同的实现类。

 IntStream.range(0, alphabet.size())
         .boxed()
         .collect(toMap(alphabet::get, Function.identity()));

原文由 akhil_mittal 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题