Nếu tôi hiểu rõ bạn đang cố gắng tính symmetric difference giữa hai bộ bản đồ nhập.
Map<String, Object> map1;
Map<String, Object> map2;
Set<Entry<String, Object>> diff12 = new HashSet<Entry<String, Object>>(map1.entrySet());
Set<Entry<String, Object>> diff21 = new HashSet<Entry<String, Object>>(map2.entrySet());
Set<Entry<String, Object>> result;
diff12.removeAll(map2.entrySet());
diff21.removeAll(map1.entrySet());
diff12.addAll(diff21);
Xem xét hành vi khó xử mà bạn đã đề cập, chúng ta hãy xem xét kỹ hơn hành vi mã ở trên. Ví dụ, nếu chúng ta lấy ví dụ số từ liên kết đưa ra ở trên:
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
map1.put("d", 4);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("a", 1);
map2.put("d", 4);
map2.put("e", 5);
Sau khi tính toán sự khác biệt như hình, kết quả:
System.out.println(Arrays.deepToString(diff12.toArray()));
cho:
[e=5, c=3, b=2]
đó là kết quả chính xác. Nhưng, nếu chúng ta làm điều đó như thế này:
public class CustomInteger {
public int val;
public CustomInteger(int val) {
this.val = val;
}
@Override
public String toString() {
return String.valueOf(val);
}
}
map1.put("a", new CustomInteger(1));
map1.put("b", new CustomInteger(2));
map1.put("c", new CustomInteger(3));
map1.put("d", new CustomInteger(4));
map2.put("a", new CustomInteger(1));
map2.put("d", new CustomInteger(4));
map2.put("e", new CustomInteger(5));
cùng một thuật toán cho kết quả như sau:
[e=5, a=1, d=4, d=4, b=2, a=1, c=3]
mà không phải là chính xác (và có thể được mô tả như vụng về :))
Trong ví dụ đầu tiên bản đồ được điền với các giá trị int được tự động boxed đến các giá trị Integer.
The class Integer có triển khai riêng các phương pháp equals và hashCode.
Lớp CustomInteger không triển khai các phương pháp này sao cho nó inherits chúng từ số Object class toàn diện.
API doc cho removeAll method từ Set interface nói như sau:
Xóa khỏi chế độ thiết lập này tất cả các yếu tố của nó được chứa trong bộ sưu tập quy định (hoạt động không bắt buộc). Nếu bộ sưu tập được chỉ định cũng là một tập hợp, hoạt động này có hiệu quả sửa đổi tập hợp này sao cho giá trị của nó là sự khác biệt thiết lập bất đối xứng của hai bộ.
Để xác định phần tử nào được chứa trong cả hai bộ sưu tập, phương thức removeAll sử dụng phương thức equals của phần tử thu thập.
Và đó là bắt: Phương thức equals của Integals trả về true nếu hai giá trị số giống nhau, trong khi phương thức equals của đối tượng sẽ trả về true nếu nó là cùng một đối tượng, ví dụ: :
Integer a = 1; //autoboxing
Integer b = new Integer(1);
Integer c = 2;
a.equals(b); // true
a.equals(c); // false
CustomInteger d = new CustomInteger(1);
CustomInteger e = new CustomInteger(1);
CustomInteger f = new CustomInteger(2);
d.equals(e); //false
d.equals(f) // false
d.val == e.val //true
d.val == f.val //false
Nếu nó vẫn còn một chút mờ tôi mạnh mẽ khuyên bạn nên đọc các hướng dẫn sau đây:
Cảm ơn. Tôi nghĩ về ổi, nhưng vì điều này cần giới thiệu thư viện mới trong dự án, bette không làm điều này. – user710818
@ user710818 Bạn sẽ không hối tiếc - đó là một thư viện tuyệt vời – vitaly
@ user710818 Bạn nên sử dụng nó trong dự án của bạn – Koerr