2013-08-22 36 views
6

tôi thấy nhận xét này trên can StringBuffer objects be keys in TreeSet in Java?Tôi có cần phương thức equals và Hashcode không nếu lớp của tôi thực hiện so sánh được trong Java?

"Có 2 chiến lược xác định sử dụng với Maps trong Java (hơn hoặc ít hơn)

Băm:. Một đầu vào 'Foo' được chuyển thành một best-như- có thể cố gắng để tạo ra một số truy cập duy nhất một chỉ mục vào một mảng. (Purists, xin đừng lạm dụng tôi, tôi cố ý đơn giản hóa) Chỉ mục này là nơi mà giá trị của bạn được lưu trữ. Có khả năng là "Foo" và "Bar" thực sự tạo ra cùng một giá trị chỉ mục có nghĩa là cả hai sẽ được ánh xạ tới cùng một vị trí mảng, rõ ràng điều này không thể làm việc và do đó đó là phương thức "equals()" được sử dụng để phân biệt

So sánh: Bằng cách sử dụng phương pháp so sánh, bạn không cần bước định hướng bổ sung này vì so sánh KHÔNG BAO GIỜ tạo ra xung đột này ngay từ đầu. Chìa khóa duy nhất mà "Foo" bằng với "Foo". Một ý tưởng thực sự tốt là nếu bạn có thể định nghĩa "equals()" là compareTo() == 0; vì lợi ích nhất quán. . Không phải là một yêu cầu"

câu hỏi của tôi là như sau: nếu lớp học của tôi thực hiện so sánh, sau đó nó có nghĩa là tôi không cần phải ghi đè lên bằng và phương pháp hashcode cho việc sử dụng đối tượng của tôi như là chìa khóa trong bộ sưu tập Hash ví dụ

class Person implements Comparable<Person> { 
    int id; 
    String name; 

    public Person(int id, String name) { 
     this.id=id; 
     this.name=name; 
    } 

    public int compareTo(Person other) { 
     return this.id-other.id; 
    } 
} 
.

Bây giờ, tôi có thể sử dụng đối tượng Person của tôi trong bộ sưu tập Hashable?

+0

Bạn đã thử chưa? –

Trả lời

6

bài viết bạn Brough đang nói về TreeSet. một bộ cây là một cái cây với mỗi nút có một vị trí xác định bởi giá trị của nó trong so sánh với các giá trị khác đã có trong cây.

a hashTable lưu trữ cặp khóa/giá trị trong bảng băm. Khi sử dụng một Hashtable, bạn chỉ định một đối tượng được sử dụng làm khóa và giá trị mà bạn muốn liên kết với khóa đó. Sau đó khóa được băm và mã băm kết quả được sử dụng làm chỉ mục mà tại đó giá trị được lưu trữ trong bảng.

sự khác biệt giữa HashableTreeSet là cây cối không cần hashCode, nó chỉ cần biết nếu bạn cần lấy mục bên trái hoặc bên phải trên cây. cho rằng bạn có thể sử dụng So sánh và không có gì hơn.

trong hashTable một so sánh sẽ đủ, bởi vì nó xây dựng khác nhau, mỗi đối tượng nhận được để tế bào của mình bằng cách băm nó, không phải bằng cách so sánh nó với các mục đã có trong bộ sưu tập.

vì vậy câu trả lời là không, bạn có thể 'sử dụng Person trong hashtable chỉ với compareTo. u phải ghi đè lên hashCode()equals() cho rằng

tôi cũng đề nghị bạn đọc this bài viết về hashtables

1

nếu lớp học của tôi thực hiện so sánh, sau đó nó có nghĩa là tôi không cần phải ghi đè lên bằng và phương pháp hashcode cho việc sử dụng đối tượng của tôi như các khóa trong bộ sưu tập Hash. ví dụ:

Không, bạn vẫn cần triển khai equals()hashCode(). Các phương thức thực hiện các chức năng rất khác nhau và không thể thay thế bằng compareTo().

  • equals() trả về giá trị boolean dựa trên sự bình đẳng của đối tượng. Đây thường là số nhận dạng bình đẳng và không bình đẳng. Điều này có thể rất khác so với các lĩnh vực sử dụng để so sánh một đối tượng trong compareTo(...) mặc dù nếu nó có ý nghĩa đối với các tổ chức, phương pháp equals() có thể là:

    @Overrides 
    public boolean equals(Object obj) { 
        if (obj == null || obj.getClass() != getClass()) { 
         return false; 
        } else { 
         return compareTo((Person)obj) == 0; 
        } 
    } 
    
  • hashCode() trả về một giá trị số nguyên cho các trường hợp được sử dụng trong bảng băm để tính toán xô nó nên được đặt in Không có cách nào tương đương để có được giá trị này ra khỏi compareTo(...).

+0

Tôi gần như upvoted câu trả lời của bạn, nhưng tôi là "sử dụng' instanceof' cho 'equals'" trường. –

+0

LOL! Trên thực tế tôi cũng vậy nhưng tôi đã ở chế độ tốc độ và tôi muốn mã được chung chung trên tất cả các lớp. :-) @ ChrisJester-Young. – Gray

+1

khi bạn trả về 'compareTo ((Person) obj)' bạn trả về 'int', nhưng bằng kiểu trả về' boolean', đúng không? – eagertoLearn

2

HashTable không sử dụng bằng và hashCode. Mỗi lớp đều có các phương thức đó. Nếu bạn không thực hiện chúng, bạn kế thừa chúng.

Cho dù bạn cần triển khai chúng, phụ thuộc vào việc phiên bản được kế thừa có phù hợp với mục đích của bạn hay không. Đặc biệt, vì Person không có superclass được chỉ định, nó thừa kế các phương thức Object. Điều đó có nghĩa là một đối tượng Person chỉ bằng với chính nó.

Bạn có cần hai đối tượng Person riêng biệt được coi là bằng với các khóa HashTable không?

0

Nhu cầu TreeSet So sánh, để thêm giá trị sang phải hoặc trái của cây. HashMap cần equals() và Hashcode() phương thức có sẵn từ Object Class nhưng bạn phải ghi đè chúng cho mục đích của bạn.

0

Nếu một lớp thực hiện Comparable, điều đó sẽ gợi ý rằng các phiên bản của lớp đại diện cho các giá trị của một số loại; nói chung, khi các lớp đóng gói các giá trị, có thể tồn tại hai trường hợp riêng biệt giữ cùng một giá trị và do đó sẽ được coi là tương đương. Kể từ khi cách duy nhất để thể hiện đối tượng riêng biệt được coi là tương đương là cho họ để ghi đè equalshashCode, mà có ngụ ý rằng những điều mà thực hiện Comparable nên ghi đè equalshashCodetrừ các giá trị gói gọn trên đó compare hoạt động sẽ là duy nhất trên toàn cầu (ngụ ý các trường hợp riêng biệt đó sẽ không bao giờ được coi là tương đương).

Ví dụ đơn giản, giả sử một lớp bao gồm trường CreationRank loại long; mỗi khi một phiên bản được tạo, thành viên đó được đặt thành giá trị được tìm nạp từ một singleton AtomicLongComparable sử dụng trường đó để xếp hạng các đối tượng theo thứ tự tạo. Không có hai trường hợp riêng biệt nào của lớp sẽ báo cáo cùng một số CreationRank; do đó, cách duy nhất x.equals(y) phải là đúng nếu xy tham chiếu đến cùng một cá thể đối tượng - chính xác theo cách mặc định equalshashCode hoạt động.

BTW, có x.compare(y) trở zero nói chung nên ngụ ý rằng x.equals(y) sẽ trở thành sự thật, và ngược lại, nhưng có một số trường hợp x.equals(y) có thể sai nhưng x.compare(y) dù sao nên trở về zero. Đây có thể là trường hợp khi một đối tượng đóng gói một số thuộc tính có thể được xếp hạng và những thuộc tính khác không thể. Hãy xem xét, ví dụ: loại FutureAction giả định đóng gói DateTime và triển khai giao diện DoSomething.Những thứ như vậy có thể được xếp hạng dựa trên ngày và thời gian đóng gói, nhưng có thể không có cách nào hợp lý để xếp hạng hai mục có cùng ngày giờ nhưng các hành động khác nhau. Có equals báo cáo sai trong khi compare báo cáo số không sẽ có ý nghĩa hơn giả vờ rằng các mục không rõ ràng không tương đương nên được gọi là "bằng nhau".

Các vấn đề liên quan