java Java比较两张图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10586897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java compare two map
提问by user595234
In java, I want to compare two maps, like below, do we have existing API to do this ?
在java中,我想比较两张地图,如下所示,我们是否有现有的API来做到这一点?
Thanks
谢谢
Map<String, String> beforeMap ;
beforeMap.put("a", "1");
beforeMap.put("b", "2");
beforeMap.put("c", "3");
Map<String, String> afterMap ;
afterMap.put("a", "1");
afterMap.put("c", "333");
//--- it should give me:
b is missing, c value changed from '3' to '333'
回答by Adam
I'd use removeAll() functionality of Set to to do set differences of keys to find additions and deletions. Actual changes can be detected by doing a set difference using the entry set as HashMap.Entry implements equals() using both key and value.
我会使用 Set 的 removeAll() 功能来设置键的差异以查找添加和删除。可以通过使用设置为 HashMap.Entry 使用键和值实现 equals() 的条目进行设置差异来检测实际更改。
Set<String> removedKeys = new HashSet<String>(beforeMap.keySet());
removedKeys.removeAll(afterMap.keySet());
Set<String> addedKeys = new HashSet<String>(afterMap.keySet());
addedKeys.removeAll(beforeMap.keySet());
Set<Entry<String, String>> changedEntries = new HashSet<Entry<String, String>>(
afterMap.entrySet());
changedEntries.removeAll(beforeMap.entrySet());
System.out.println("added " + addedKeys);
System.out.println("removed " + removedKeys);
System.out.println("changed " + changedEntries);
Output
输出
added []
removed [b]
changed [c=333]
回答by Stephen C
回答by Mark Jeronimus
You could use a custom object that contains the key and the value (actually Map does this internally, hidden from the user, so we can't use that)
您可以使用包含键和值的自定义对象(实际上 Map 在内部执行此操作,对用户隐藏,因此我们无法使用它)
Put these tuples into a Set
将这些元组放入一个 Set
To compare two sets, convert them both to arrays, sort the arrays and walk both arrays from begin to end in parallel, stepping down the first array if it's key is smaller than the key in the second array, and vise versa.
要比较两个集合,请将它们都转换为数组,对数组进行排序并从头到尾并行遍历两个数组,如果第一个数组的键小于第二个数组中的键,则递减第一个数组,反之亦然。
class Tuple implements Comparable<Tuple>
{
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<Tuple> beforeSet = new TreeSet<>();
beforeSet.add(new Tuple("a", "1"));
beforeSet.add(new Tuple("b", "2"));
beforeSet.add(new Tuple("c", "4"));
Set<Tuple> 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++;
}
}
}
回答by mprivat
There isn't any out of the box component to help with that. You'll probably have to code it unfortunately. The good news is the logic is pretty easy.
没有任何开箱即用的组件可以帮助解决这个问题。不幸的是,您可能不得不对其进行编码。好消息是逻辑很简单。
回答by atk
Depending upon your particular needs, you might also consider using other applications designed to do this work, like diff. You could write the two maps to two different files, and diff the files.
根据您的特定需求,您还可以考虑使用其他专为完成这项工作而设计的应用程序,例如 diff。您可以将两个映射写入两个不同的文件,然后对这些文件进行比较。
回答by sjakubowski
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);
回答by tinker_fairy
@user595234 To Compare the two Maps you can add the keys of a map to list and with those 2 lists you can use the methods retainAll() and removeAll() and add them to another common keys list and different keys list. Using the keys of the common list and different list you can iterate through map, using equals you can compare the maps.
@user595234 要比较这两个映射,您可以将映射的键添加到列表中,对于这两个列表,您可以使用方法 retainAll() 和 removeAll() 并将它们添加到另一个公共键列表和不同的键列表中。使用公共列表和不同列表的键可以遍历映射,使用equals 可以比较映射。
public class Demo
{
public static void main(String[] args)
{
Map<String, String> beforeMap = new HashMap<String, String>();
beforeMap.put("a", "1");
beforeMap.put("b", "2");
beforeMap.put("c", "3");
Map<String, String> afterMap = new HashMap<String, String>();
afterMap.put("a", "1");
afterMap.put("c", "333");
System.out.println("Before "+beforeMap);
System.out.println("After "+afterMap);
List<String> beforeList = getAllKeys(beforeMap);
List<String> afterList = getAllKeys(afterMap);
List<String> commonList1 = beforeList;
List<String> commonList2 = afterList;
List<String> diffList1 = getAllKeys(beforeMap);
List<String> 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<String> getAllKeys(Map<String, String> map1)
{
List<String> key = new ArrayList<String>();
if (map1 != null)
{
Iterator<String> mapIterator = map1.keySet().iterator();
while (mapIterator.hasNext())
{
key.add(mapIterator.next());
}
}
return key;
}
}
The below code will give you this output:
下面的代码会给你这个输出:
Before: {b=2, c=3, a=1}
After: {c=333, a=1}
Unequal: Before- 3 After- 333
Equal: Before- 1 After- 1
Values present only in before map: 2
Before: {b=2, c=3, a=1}
After: {c=333, a=1}
Unequal: Before- 3 After- 333
Equal: Before- 1 After- 1
仅存在于 before 映射中的值:2