2012-05-14 59 views
14

Trong java, tôi muốn so sánh hai bản đồ, như dưới đây, chúng ta có API hiện tại để làm điều này không?Java so sánh hai bản đồ

Cảm ơn

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' 
+0

Tôi không nghĩ rằng có API ngoài hộp cho việc này. Bạn cần mã hóa logic. – kosa

+1

bản sao có thể có của [cách so sánh hai bản đồ băm?] (Http://stackoverflow.com/questions/4591988/how-to-compare-two-hash-maps) –

Trả lời

26

Tôi muốn sử dụng chức năng removeAll() của Set để đặt các khác biệt của các phím để tìm thêm và xóa. Thay đổi thực tế có thể được phát hiện bằng cách thực hiện một sự khác biệt thiết lập bằng cách sử dụng các thiết lập mục nhập như HashMap.Entry thực hiện bằng() sử dụng cả khóa và giá trị.

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] 
+1

Kẻ phản đối Trả lời: "Vì Khoa học!" Đùa thôi. Câu trả lời chính xác. +1 –

1

Không có bất kỳ là ra khỏi thành phần hộp để giúp với điều đó. Có thể bạn sẽ phải viết mã không may. Tin tốt là logic khá dễ.

1

Tùy thuộc vào nhu cầu cụ thể của bạn, bạn cũng có thể cân nhắc việc sử dụng các ứng dụng khác được thiết kế để thực hiện công việc này, như khác biệt. Bạn có thể viết hai bản đồ vào hai tệp khác nhau và phân biệt các tệp.

10

Lớp ổi Maps có một số phương pháp để tính toán sự khác biệt giữa một cặp bản đồ. Tuy nhiên, những phương pháp này cung cấp cho bạn một cấu trúc dữ liệu đại diện cho sự khác biệt không phải là một chuỗi được in đẹp.

1

Bạn có thể sử dụng một đối tượng tùy chỉnh có chứa chìa khóa và giá trị (trên thực tế Bản đồ thực hiện điều này trong nội bộ, ẩn từ người dùng, vì vậy chúng tôi không thể sử dụng đó)

Đặt những tuples thành một Set

Để so sánh hai bộ, chuyển đổi cả hai thành mảng, sắp xếp mảng và đi bộ cả hai mảng từ đầu đến cuối song song, bước xuống mảng đầu tiên nếu khóa đó nhỏ hơn khóa trong mảng thứ hai và ngược lại.

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

@ user595234 Để so sánh hai Maps, bạn có thể thêm các phím của một bản đồ để liệt kê và với những 2 danh sách mà bạn có thể sử dụng các phương pháp retainAll() và RemoveAll() và thêm chúng vào danh sách khóa phổ biến khác và danh sách các phím khác nhau. Sử dụng các phím của danh sách chung và danh sách khác nhau mà bạn có thể lặp qua bản đồ, bằng cách sử dụng bằng bạn có thể so sánh bản đồ.

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

Mã dưới đây sẽ cung cấp cho bạn kết quả này:

Trước: {b=2, c=3, a=1}
Sau: {c=333, a=1}
bất bình đẳng: Before- 3 dịch vụ hậu mãi 333
Equal: Before- 1 sau giờ 1
Giá trị chỉ hiện diện trước bản đồ: 2

+0

bạn cũng có thể sử dụng MultiValueMap của org.apache.commons.collections.map –