我只需要找到 2 张地图之间的差异,而不同的可能是缺少键或键值不同。
我找到了地图之间差异的一般答案
sources.removeAll(targets) ... leaves only entries in sources that are only in sources, not in target
而
sources.retainAll(targets) ... leaves only entries that are in both sets
但我不确定它是否比以下代码更好,因为我还需要检查密钥是否存在值是否不同
Map<K, V> updatedMap = new EnumMap<>(K.class);
for (Map.Entry<K, V> finalSet : secondMap.entrySet()) {
K currentKey = finalSet.getKey();
if (!firstMap.containsKey(currentKey) || firstMap.get(currentKey) != finalSet.getValue()) {
updatedMap.put(currentKey, finalSet.getValue());
firstMap.remove(currentKey);
}
}
for (Map.Entry<K, V> currentSet : firstMap.entrySet()) {
K currentKey = currentSet.getKey();
if (!secondMap.containsKey(currentKey)) {
updatedMap.put(currentKey, currentSet.getValue());
} else if (secondMap.get(currentKey) != currentSet.getValue()) {
updatedMap.put(currentKey, secondMap.get(currentKey));
}
}
它们是查找地图(包括值(之间差异的更好方法吗?
好吧,你可以比较Map
的Entry
,因为该类以你想要的方式覆盖equals/hashCode
。目前还不完全清楚您要保留哪些条目,来自左侧地图或右侧地图的条目或其中任何一个。
例如,这可以通过以下方法完成:
Map<Integer, String> allDifs =
Sets.symmetricDifference(left.entrySet(), right.entrySet())
.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
另一方面,如果您只想保留第二(右(Map
的条目:
Map<Integer, String> result =
Sets.difference(right.entrySet(), left.entrySet())
.stream()
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
System.out.println(result);
显然,您需要为此guava
和java-8
...
编辑
你真正想要的不是用Collectors.toMap
实现的,但你可以用:
Map<Integer, String> result = new HashMap<>();
Sets.symmetricDifference(right.entrySet(), left.entrySet())
.stream()
.forEachOrdered(x -> {
String previousValue = result.putIfAbsent(x.getKey(), x.getValue());
if (previousValue != null) {
result.replace(x.getKey(), right.get(x.getKey()));
}
});
使用 Guava 的Maps.difference(Map, Map)
.
他们的维基解释了它是如何工作的,但你可以在下面找到你的问题的解决方案。
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
Map<String, Integer> right = ImmutableMap.of("b", 2, "c", 4, "d", 5);
MapDifference<String, Integer> diff = Maps.difference(left, right);
Map<String, Integer> output = new HashMap<>();
output.putAll(diff.entriesOnlyOnLeft());
output.putAll(diff.entriesOnlyOnRight());
for (Map.Entry<String,MapDifference.ValueDifference<Integer>> e: diff.entriesDiffering().entrySet()) {
// Java 10 and later : for (var e: diff.entriesDiffering().entrySet())
output.put(e.getKey(), e.getValue().rightValue());
}
System.out.println(output); // {a=1, c=4, d=5}