我只需要找到两张地图之间的差异,而不同的可能是缺少密钥或密钥的不同值。
的一般答案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));
}
}
他们是更好的方法来找到包括值的地图之间的差异吗?
答案 0 :(得分:2)
好吧,您可以比较Entry
中的Map
,因为该类会以您想要的方式覆盖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()));
}
});
答案 1 :(得分:1)
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}