簡體   English   中英

Java比較兩個地圖

[英]Java compare two map

在java中,我想比較兩個地圖,如下所示,我們是否有現有的API來執行此操作?

謝謝

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'

我將使用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);

產量

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

Guava Maps類有一些方法可以計算一對地圖之間的差異。 但是,這些方法為您提供了一個表示差異的數據結構,而不是一個漂亮的打印字符串。

沒有任何開箱即用的組件可以幫助解決這個問題。 不幸的是,你可能不得不編碼。 好消息是邏輯非常簡單。

根據您的特定需求,您可能還會考慮使用其他旨在完成此項工作的應用程序,例如diff。 您可以將兩個映射寫入兩個不同的文件,並對文件進行區分。

您可以使用包含鍵和值的自定義對象(實際上Map在內部執行此操作,對用戶隱藏,因此我們無法使用它)

將這些元組放入Set

要比較兩個集合,將它們轉換為數組,對數組進行排序並從頭到尾並行地遍歷兩個數組,如果第一個數組的鍵小於第二個數組中的鍵,則逐步調低第一個數組,反之亦然。

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++;
        }
    }
}
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);

@ user595234要比較兩個地圖,您可以將地圖的鍵添加到列表中,使用這兩個列表,您可以使用方法retainAll()和removeAll(),並將它們添加到另一個公共鍵列表和不同的鍵列表中。 使用公共列表和不同列表的鍵,您可以迭代地圖,使用等於您可以比較地圖。

    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;
            }
    }

下面的代碼將為您提供此輸出:

之前: {b=2, c=3, a=1}
之后: {c=333, a=1}
不平等:之前 - 3之后 - 333
平等:之前 - 1之后 - 1
值僅出現在map之前:2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM