从 hashmap1 中查找 add/remove 的哪些键和值等于 hashmap2
Finding which keys and values to add/remove from hashmap1 to be equal to hashmap2
假设我有以下情况:
我想从 hashmap1 中找到 add/remove 的哪些键和值,以便 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);
但我找不到将键和值放在一起的简单方法
But I could not found a simple way to get both keys and values together
是的,您可以使用 entrySet() 方法从映射中同时获取键和值。
然后就可以这样使用了
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
一种方法是首先将 Map<String, List<String>>
展平为许多 对。然后对其进行操作。最后将结果组合回 Map<String, List<String>>
.
因此,首先,您需要编写执行展平和合并的辅助方法:
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]}
假设我有以下情况:
我想从 hashmap1 中找到 add/remove 的哪些键和值,以便 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);
但我找不到将键和值放在一起的简单方法
But I could not found a simple way to get both keys and values together
是的,您可以使用 entrySet() 方法从映射中同时获取键和值。
然后就可以这样使用了
for (var entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
一种方法是首先将 Map<String, List<String>>
展平为许多 Map<String, List<String>>
.
因此,首先,您需要编写执行展平和合并的辅助方法:
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]}