【问题标题】:Finding which keys and values to add/remove from hashmap1 to be equal to hashmap2查找要从 hashmap 1 添加/删除的键和值等于 hashmap 2
【发布时间】:2021-11-03 17:00:22
【问题描述】:

假设我有以下情况:

我想找出要从 hashmap1 中添加/删除的键和值,以便 hashmap1 和 hashmap2 具有相同的值。

hashmap1: {obj2=[Brazil], obj1=[Argentina, Chile, Brazil], obj3Mobile=[Russia]}

hashmap2: {obj3Op=[Germany], obj2=[Brazil, China], obj1=[Argentina, Brazil]}

我的预期输出是:

add:  {obj2=[China], obj3Op=[Germany]}

remove: {obj3Mobile=[Russia], obj1=[Chile]}

为了重现数据集:

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;

public class Main
{
    public static void main(String[] args) {
        Map<String, List<String>> dictOP = new HashMap<String, List<String>>();
        Map<String, List<String>> dictMobile = new HashMap<String, List<String>>();
        
        List<String> obj1Mobile = new ArrayList<String>();
        List<String> obj2Mobile = new ArrayList<String>();
        List<String> obj3Mobile = new ArrayList<String>();
        
        List<String> obj1Op = new ArrayList<String>();
        List<String> obj2Op = new ArrayList<String>();
        List<String> obj3Op = new ArrayList<String>();
        
        
        obj1Mobile.add("Argentina");
        obj1Mobile.add("Chile");
        obj1Mobile.add("Brazil");
        obj2Mobile.add("Brazil");
        obj3Mobile.add("Russia");
        
        
        obj1Op.add("Argentina");
        obj1Op.add("Brazil");
        obj2Op.add("Brazil");
        obj2Op.add("China");
        obj3Op.add("Germany");
        
        dictOP.put("obj1", obj1Op);
        dictOP.put("obj2", obj2Op);
        dictOP.put("obj3Op", obj3Op);
        
        dictMobile.put("obj1", obj1Mobile);
        dictMobile.put("obj2", obj2Mobile);
        dictMobile.put("obj3Mobile", obj3Mobile);
        
        System.out.println(dictMobile);
        System.out.println(dictOP);
        

    }
}

使用下面的这种方法,我只能找到要添加和删除的键。

    //Union of keys from both maps
    HashSet<String> removeKey = new HashSet<>(dictMobile.keySet());
    removeKey.addAll(dictOP.keySet());
    removeKey.removeAll(dictMobile.keySet());
     
    HashSet<String> addKey = new HashSet<>(dictOP.keySet());
    addKey.addAll(dictMobile.keySet());
    addKey.removeAll(dictOP.keySet());
    
    System.out.println(removeKey);
    System.out.println(addKey);

但我找不到一种简单的方法来将键和值放在一起

【问题讨论】:

  • 一种“同时获取键和值的简单方法”将获得地图接口的entrySet() 方法。

标签: java hashmap


【解决方案1】:

一种方法是首先将Map&lt;String, List&lt;String&gt;&gt; 扁平化为许多 对。然后对其进行操作。最后将结果组合回Map&lt;String, List&lt;String&gt;&gt;

所以首先,您需要编写辅助方法来进行展平和合并:

private static Set<Entry<String, String>> flatten(Map<String, List<String>> map) {
    return map.entrySet().stream().flatMap(e ->
          e.getValue().stream().map(v -> Map.entry(e.getKey(), v))
        )
        .collect(Collectors.toSet());
}

private static Map<String, List<String>> group(Set<Map.Entry<String, String>> entries) {
    return entries.stream().collect(Collectors.groupingBy(
        Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())
    ));
}

那么就很直接了:

var mobileEntries = flatten(dictMobile);
var opEntries = flatten(dictOP);
var add = new HashSet<>(opEntries);
add.removeAll(mobileEntries);
var remove = new HashSet<>(mobileEntries);
remove.removeAll(opEntries);
System.out.println(group(add));
System.out.println(group(remove));

打印出来:

{obj3Op=[Germany], obj2=[China]}
{obj1=[Chile], obj3Mobile=[Russia]}

【讨论】:

  • 非常感谢@Sweeper
【解决方案2】:

但我找不到一种简单的方法来将键和值放在一起

是的,您可以使用 entrySet() 方法从映射中同时获取键和值。

然后你就可以这样使用了

for (var entry : map.entrySet()) {
    System.out.println(entry.getKey() + "/" + entry.getValue());
}

【讨论】:

    猜你喜欢
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    • 2014-03-07
    • 1970-01-01
    相关资源
    最近更新 更多