Java比较两个地图

在java中,我想比较两个地图,如下所示,我们是否有现有的API来执行此操作?

谢谢

Map beforeMap ; beforeMap.put("a", "1"); beforeMap.put("b", "2"); beforeMap.put("c", "3"); Map afterMap ; afterMap.put("a", "1"); afterMap.put("c", "333"); //--- it should give me: b is missing, c value changed from '3' to '333' 

我将使用Set的removeAll()function来设置键的差异以查找添加和删除。 可以通过使用条目集HashMap进行设置差异来检测实际更改.Entry使用键和值实现equals()。

 Set removedKeys = new HashSet(beforeMap.keySet()); removedKeys.removeAll(afterMap.keySet()); Set addedKeys = new HashSet(afterMap.keySet()); addedKeys.removeAll(beforeMap.keySet()); Set> changedEntries = new HashSet>( afterMap.entrySet()); changedEntries.removeAll(beforeMap.entrySet()); System.out.println("added " + addedKeys); System.out.println("removed " + removedKeys); System.out.println("changed " + changedEntries); 

产量

 added [] removed [b] changed [c=333] 

Guava Maps类有一些方法可以计算一对地图之间的差异。 但是,这些方法为您提供了一个表示差异的数据结构,而不是一个漂亮的打印字符串。

没有任何开箱即用的组件可以帮助解决这个问题。 不幸的是,你可能不得不编码。 好消息是逻辑非常简单。

根据您的特定需求,您可能还会考虑使用其他旨在完成此项工作的应用程序,例如diff。 您可以将两个映射写入两个不同的文件,并对文件进行区分。

 String output = new String(); for (String key:beforeMap.getKeys()){ String beforeValue = beforeMap.getValue(key); String afterValue = afterMap.getValue(key); //nullsafe if(beforeValue.equals(afterValue){} else if (afterValue == null){ output = output + key + " is missing, "; continue; }else { output = output + key + " has changed from " + beforeValue + " to " + afterValue + " , "; } afterMap.remove(key); } for (String key:afterMap.getKeys()){ output = output + key + " was added with value " + afterMap.getValue(key) + ", "; } if(output == null){ output = "Same map"; } output = output.substring(0,output.length-2); System.out.println(output); 

您可以使用包含键和值的自定义对象(实际上Map在内部执行此操作,对用户隐藏,因此我们无法使用它)

将这些元组放入Set

要比较两个集合,将它们转换为数组,对数组进行排序并从头到尾并行地遍历两个数组,如果第一个数组的键小于第二个数组中的键,则逐步调低第一个数组,反之亦然。

 class Tuple implements Comparable { public String key; public String value; public Tuple(String key, String value) { this.key = key; this.value = value; } @Override public int compareTo(Tuple o) { return key.compareTo(o.key); } } public static void main(String[] args) { // TreeSet is already sorted. If you use HashSet, use Arrays.sort() Set beforeSet = new TreeSet<>(); beforeSet.add(new Tuple("a", "1")); beforeSet.add(new Tuple("b", "2")); beforeSet.add(new Tuple("c", "4")); Set afterSet = new TreeSet<>(); afterSet.add(new Tuple("a", "1")); afterSet.add(new Tuple("c", "333")); afterSet.add(new Tuple("aa", "4")); Tuple[] beforeArray = beforeSet.toArray(new Tuple[beforeSet.size()]); Tuple[] afterArray = afterSet.toArray(new Tuple[afterSet.size()]); int beforePtr = 0; int afterPtr = 0; while (beforePtr < beforeArray.length || afterPtr < afterArray.length) { int difference = afterPtr >= afterArray.length? -1 : beforePtr >= beforeArray.length? 1 : beforeArray[beforePtr].compareTo(afterArray[afterPtr]); if (difference == 0) { if (!beforeArray[beforePtr].value.equals(afterArray[afterPtr].value)) { System.out.println(beforeArray[beforePtr].key + " value changed from '" + beforeArray[beforePtr].value + "' to '" + afterArray[afterPtr].value + "'"); } beforePtr++; afterPtr++; } else if (difference < 0) { System.out.println(beforeArray[beforePtr].key + " is missing"); beforePtr++; } else { System.out.println(afterArray[afterPtr].key + " is added"); afterPtr++; } } } 

@ user595234要比较两个地图,您可以将地图的键添加到列表中,使用这两个列表,您可以使用方法retainAll()和removeAll(),并将它们添加到另一个公共键列表和不同的键列表中。 使用公共列表和不同列表的键,您可以迭代地图,使用等于您可以比较地图。

  public class Demo { public static void main(String[] args) { Map beforeMap = new HashMap(); beforeMap.put("a", "1"); beforeMap.put("b", "2"); beforeMap.put("c", "3"); Map afterMap = new HashMap(); afterMap.put("a", "1"); afterMap.put("c", "333"); System.out.println("Before "+beforeMap); System.out.println("After "+afterMap); List beforeList = getAllKeys(beforeMap); List afterList = getAllKeys(afterMap); List commonList1 = beforeList; List commonList2 = afterList; List diffList1 = getAllKeys(beforeMap); List diffList2 = getAllKeys(afterMap); commonList1.retainAll(afterList); commonList2.retainAll(beforeList); diffList1.removeAll(commonList1); diffList2.removeAll(commonList2); System.out.println("Common List of before map "+commonList1); System.out.println("Common List of after map "+commonList2); System.out.println("Diff List of before map "+diffList1); System.out.println("Diff List of after map "+diffList2); if(commonList1!=null & commonList2!=null) // athough both the size are same { for (int i = 0; i < commonList1.size(); i++) { if ((beforeMap.get(commonList1.get(i))).equals(afterMap.get(commonList1.get(i)))) { System.out.println("Equal: Before- "+ beforeMap.get(commonList1.get(i))+" After- "+afterMap.get(commonList1.get(i))); } else { System.out.println("Unequal: Before- "+ beforeMap.get(commonList1.get(i))+" After- "+afterMap.get(commonList1.get(i))); } } } if (CollectionUtils.isNotEmpty(diffList1)) { for (int i = 0; i < diffList1.size(); i++) { System.out.println("Values present only in before map: "+beforeMap.get(diffList1.get(i))); } } if (CollectionUtils.isNotEmpty(diffList2)) { for (int i = 0; i < diffList2.size(); i++) { System.out.println("Values present only in after map: "+afterMap.get(diffList2.get(i))); } } } /** getAllKeys API adds the keys of the map to a list */ private static List getAllKeys(Map map1) { List key = new ArrayList(); if (map1 != null) { Iterator mapIterator = map1.keySet().iterator(); while (mapIterator.hasNext()) { key.add(mapIterator.next()); } } return key; } } 

以下代码将为您提供此输出:

之前: {b=2, c=3, a=1}
之后: {c=333, a=1}
不平等:之前 – 3之后 – 333
平等:之前 – 1之后 – 1
值仅出现在map之前:2