【问题标题】:Merging map and modifying value合并地图和修改值
【发布时间】:2016-01-10 05:28:57
【问题描述】:

有两张地图,我正在尝试将它们合并为一张地图 (finalResp)。

Map<String, String[]> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>();

HashMap<String, String> finalResp = new HashMap<String, String>();

解决方案 - Java 8 之前的 - 实现如下:

for (Map.Entry<String, String[]> entry : map1.entrySet()) {
    if (map2.containsKey(entry.getKey())) {
        String newValue  = changetoAnother(map1.get(entry.getKey()), map2.get(entry.getKey()));
        finalResp.put(entry.getKey(), newValue);
    }
}

使用 Java 8,我陷入了困境:

HashMap<String, String> map3 = new HashMap<>(map2);
map1.forEach((k, v) -> map3.merge(k, v, (i, j) -> mergeValue(i, j) ));

如何检查地图 1 中是否不存在地图 2 的键并修改值?

【问题讨论】:

    标签: java collections lambda java-8 java-stream


    【解决方案1】:

    一种可能的方法是过滤不需要的元素(不包含在map2 中)并将结果收集到新的地图中:

    Map<String, String> finalResp = 
        map1.entrySet().stream().filter(e -> map2.containsKey(e.getKey()))
                                .collect(Collectors.toMap(
                                    Entry::getKey, 
                                    e -> changetoAnother(e.getValue(), map2.get(e.getKey()))
                                ));
    

    另一种方法是创建map2 的副本,保留此Map 的所有键也包含在map1 键中,最后通过应用函数changetoAnother 替换所有值。

    Map<String, String> result = new HashMap<>(map2);
    result.keySet().retainAll(map1.keySet());
    result.replaceAll((k, v) -> changetoAnother(map1.get(k), v));
    

    请注意,第一个解决方案的优点是它可以很容易地泛化为适用于任何两个地图:

    private <K, V, V1, V2> Map<K, V> merge(Map<K, V1> map1, Map<K, V2> map2, BiFunction<V1, V2, V> mergeFunction) {
        return map1.entrySet().stream()
                              .filter(e -> map2.containsKey(e.getKey()))
                              .collect(Collectors.toMap(
                                  Entry::getKey, 
                                  e -> mergeFunction.apply(e.getValue(), map2.get(e.getKey()))
                              ));
    }
    

    Map<String, String> finalResp = merge(map1, map2, (v1, v2) -> changetoAnother(v1, v2));
    

    【讨论】:

    • 太棒了!谢谢,但是当我在我的代码中使用时,我得到一个编译器警告“在封闭范围中定义的局部变量 map2 必须是最终的或有效的最终”。在我的代码中,像这样获取 map2 的值,Map map2 = getRespItemMap(response);
    • 使用广义方法后,错误消失了。 finalResp = merge(map1, map2, (v1, v2) -> changetoAnother(v1, v2));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-02
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多