【问题标题】:Java 8 list to existing mapJava 8 列表到现有地图
【发布时间】:2017-03-21 20:18:38
【问题描述】:

我有一张地图Map<Id,Map<Obj1,Obj2>> existingMap and List<Obj1> list; 我需要将列表值添加到映射作为键和新映射作为值。

我试图做类似的事情:

existingMap.putAll(list.stream().map(x->x.getId()).collect(
Collectors.toMap(x, x -> Map<Obj1,Obj2>::new);

我应该怎么写?以及如何使用参数化构造函数来对抗默认值?

【问题讨论】:

  • 地图是一个接口。您不能在界面上使用 new 。选择一个具体的 Map 实现(例如 HashMap)
  • 也就是说,一个好的旧 for 循环在这里会更具可读性,IMO
  • 如果列表包含的元素是地图中的现有键怎么办?你应该失败吗?破坏旧值?保留当前条目?

标签: java dictionary lambda java-8 hashmap


【解决方案1】:

试试:

list.forEach(e -> existingMap.put(e.getId(), new HashMap<>()));

仍然使用函数式 Java 8 功能,效果相同。

for-loop 等效:

for(Id id : list)
    existingMap.put(id.getId(), new HashMap<>());

您的代码有问题:

  • Map 是一个接口,不能被实例化。例如,使用HashMapTreeMap 之类的具体实现。

  • Collectors#toMap 接受 两个 Functions。如果你想使用你的格式,你需要:

    Collectors.toMap(x -> x, HashMap::new)   
    

    注意 lambda x -&gt; x 而不是简单的 x

    编辑:当然,您可以使用更详细的Function.identity(),而不是x -&gt; x,但根据您的需要,这可能更具表现力。

【讨论】:

  • 谢谢!就是这么简单!我当然使用 HashMap。只是快速写了问题。
【解决方案2】:

还有一种方法是应用收集器进行转换:

List<Id> list = ...
Map<Id, Map<Obj1, Obj2>> extension = list.stream().collect(
        toMap(
                identity(),
                value -> new HashMap<Obj1, Obj2>()
        )
);

existingMap.putAll(extension);

您必须添加以下导入才能使其工作:

import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toMap;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多