2010-11-02 11 views
16

Tất cả,Sự bình đẳng giữa 2 HashMap

Trong phương thức equals() của lớp, tôi đang sử dụng biến cá thể HashMap để so sánh bình đẳng. Tuy nhiên, 2 đối tượng khác nhau vẫn hiển thị bằng nhau khi so sánh các biến HashMap của chúng. Nghiên cứu tiếp theo đã đưa tôi đến liên kết: Link Here. Tuy nhiên, nó chỉ nói rằng lý do cho HashMap1.equals (HashMap2) không hoạt động là vì "các mảng Java được cách ly không thể được kiểm tra bình đẳng mà không cần viết mã tùy chỉnh."

Tôi không hiểu lý do này. Bất cứ ai có thể xin vui lòng hướng dẫn tôi đến một lý do phức tạp?

Trả lời

21

Phương thức equals trên loại mảng Java tương đương với ==, vì mảng Java "lớp" không ghi đè Object.equals.

Nếu bạn muốn so sánh các mảng "theo giá trị", bạn cần phải sử dụng phương pháp java.util.Arrays.equals(...) thích hợp hoặc tự mình triển khai.

Nếu HashHap sử dụng mảng làm khóa hoặc giá trị, điều này sẽ làm cho HashMap.equals hoạt động lạ lùng (từ góc nhìn của bạn). Đó là những gì bài báo được liên kết đang nói. Tuy nhiên, mảng ngữ nghĩa chỉ ảnh hưởng đến HashMap bình đẳng nếu bạn sử dụng mảng làm (hoặc trong) các khóa chính hoặc giá trị. Nếu không, thì equals chỉ hoạt động như mong đợi.

(The javadocs cho bình đẳng trên Map lớp học được một chút liên quan, nhưng họ về cơ bản đun sôi xuống để lấy hai bộ nhập cảnh, so sánh kích thước của chúng, và sau đó làm s1.containsAll(s2). Tất nhiên, điều này là tốn kém, nhưng nó nên làm việc cho tất cả các lớp Map triển khai chính xác giao diện Map.)

3

Các mảng Java nguyên gốc không có hàm .equals(). Vì vậy, nếu các giá trị của băm (hoặc các khóa mà tôi giả định) là các mảng, HashMap.equals() sẽ thất bại. Tôi nghi ngờ nó sẽ rơi trở lại trên Object.equals() mà chỉ cần kiểm tra xem hai đối tượng thực sự là cùng một đối tượng.

// something like this 
class Object { 
    public boolean equals(Object o) { 
    return this == o; 
    } 
} 

Bạn có thể để bên ngoài vấn đề bằng cách sử dụng một số biến thể trên một container chứ không phải là một mảng [], như container có Equals riêng của họ() trong đó kêu gọi equals() trên các yếu tố liên tiếp trong những container chứ không phải chỉ đơn giản là kiểm tra nếu chúng là cùng một tham chiếu. Các mã cho một thực hiện Collection.equals có thể giống như thế:

public boolean equals(Object o) { 
    // sets never equal lists and visa versa 
    if (o instanceof MyCollectionSubclass) { 
    Iterator myIterator = iterator(); 
    Iterator theirIterator = ((Collection)o).iterator(); 
    while (myIterator.hasNext() && theirIterator.hasNext()) { 
     Object myObj = myIterator.next(); 
     Object theirObj = theirIterator.next(); 
     if (!myObj.equals(theirObj)) { 
     return false; 
     } 
    } 
    // at least one will be false or we wouldn't have left the above while loop 
    return myIterator.hasNext() == theirIterator.hasNext(); 
    } 
    // not our class 
    return false; 
} 

Điều này có thể tạo ra một sự so sánh giá trị thực sự phụ thuộc vào những gì nội dung của bộ sưu tập làm gì khi bạn gọi equals() của họ.

+1

Mảng được kế thừa từ Đối tượng và có cùng triển khai với đối tượng. –

+0

Đó là những gì tôi nghĩ, mặc dù tôi không bận tâm tìm kiếm nó. –

6

Bài viết là đúng. Hashmaps có thể được so sánh một cách an toàn bằng cách sử dụng phương thức equals() miễn là các đối tượng chính và các đối tượng giá trị có thể so sánh bằng cách sử dụng cùng một phương thức. Trong bài viết, các giá trị bản đồ là các mảng, không thực hiện equals() như mong đợi. Sử dụng ArrayList thay vào đó sẽ giải quyết được vấn đề.

2

mảng Java không thể được kiểm tra cho sự bình đẳng mà không cần viết mã tùy chỉnh

Đây chỉ là một cách phức tạp để nói rằng mảng Java không ghi đè Object.equals().Do đó nếu bạn so sánh chúng bằng cách sử dụng equals() (đó là những gì các phương pháp equals của tất cả các lớp sưu tập làm), bạn nhận được "bình đẳng thể hiện", thay vì "bình đẳng giá trị".

Đó thực sự chỉ là trường hợp đặc biệt theo các cách khác nhau equals hoạt động tùy thuộc vào việc nó có bị ghi đè hay không.