2013-11-26 15 views
5

Tại sao tài liệu API Oracle Java cho phương pháp add() cho TreeSetHashSet trạng thái đó:tắc được sử dụng trong tài liệu Java

một yếu tố điện tử được thêm vào chỉ nếu không có e2 trong tập nơi (e==null ? e2==null : e.equals(e2))

Tuy nhiên, TreeSet sử dụng compareTo(), trong khi HashSet sử dụng để xác định hashCode()bình đẳng. Cả hai đều bỏ qua giá trị của equals(). Tôi lo ngại rằng tài liệu không chính xác, hay là sự hiểu biết của tôi về quy ước hoặc thuật toán bị lỗi?

Trả lời

2

Bạn đúng là tài liệu TreeSet không chính xác.

Bạn không chính xác về HashSet, vì nó không sử dụng equals(). hashCode()không phải được sử dụng để kiểm tra bình đẳng, chỉ để tìm kiếm nhanh.

+0

Nếu hashCode() được đặt để luôn trả về cùng mã thì hành vi của add() có vẻ phụ thuộc vào equals(). Nhưng nếu tôi tạo một đối tượng bằng equals() luôn trả về 'true' và không ghi đè hashCode() - vì vậy nó khác với các đối tượng khác nhau - sau đó add() sẽ thêm nhiều đối tượng. Vì vậy, hành vi của add() có vẻ phức tạp hơn như đã nêu trong tài liệu. Như Louis nói, những tình huống này nằm ngoài hợp đồng, nhưng tôi đã quan tâm đến việc thực hiện (vì nó không làm những gì nó nói) - bất cứ ai biết liệu có một đặc tả kinh điển không? – user3038094

+0

@ user3038094 - tôi khuyên bạn nên đọc về cách HashMap hoạt động. thì bạn sẽ hiểu tại sao phương thức 'equals()' không phải lúc nào cũng được gọi. bất kể, theo nghĩa chung, HashSet _does_ sử dụng 'equals()' để kiểm tra bình đẳng. – jtahlborn

+0

Cảm ơn jtahlborn - Tôi đã theo lời khuyên của bạn và xem ý bạn là gì. Nếu hashCode() là khác nhau thì thuật toán không làm phiền việc đánh giá equals(), nó chỉ sử dụng equals() nếu hashCode() là giống nhau. Có lẽ điều này là bởi vì hashCode() được giả định là nhanh hơn để đánh giá hơn bằng(), hoặc là nó để làm với thực tế là hashCode() sẽ phải được đánh giá? Vì vậy, sẽ tốt hơn nếu bạn nói trong tài liệu: e == null? e2 == null: e.hashCode() == e2.hashCode()? e.hashCode() == e2.hashCode(): e.equals (e2) == 0 – user3038094

1

TreeSet giải thích điều này trong doc của nó:

Lưu ý rằng thứ tự được duy trì bởi một bộ (đã hoặc chưa một so sánh rõ ràng được cung cấp) phải phù hợp với bằng nếu nó là để thực hiện một cách chính xác giao diện Set. Điều này là do giao diện Set được định nghĩa theo phương thức equals, nhưng một thể hiện TreeSet thực hiện tất cả các so sánh phần tử bằng cách sử dụng phương thức compareTo (hoặc so sánh) của nó, vì vậy hai các yếu tố được coi là bằng nhau theo phương pháp này, từ quan điểm của tập hợp, bằng nhau. Hành vi của một tập hợp được xác định rõ ngay cả khi thứ tự của nó là không phù hợp với bằng; nó không tuân theo hợp đồng chung của giao diện Set.

Đối với HashSet, đó là một kỳ vọng tiềm ẩn của tài liệu mà các đối tượng trong Set được triển khai chính xác; nếu hashCode() không được triển khai chính xác, thì không phải là HashSet vi phạm thông số kỹ thuật của nó nhưng các đối tượng được truyền cho nó.

+0

"Hành vi của một tập hợp được xác định rõ ngay cả khi thứ tự của nó là không phù hợp với bằng." Tuy nhiên, hành vi không được định nghĩa trong tài liệu, đó là những gì tôi đã tự hỏi. Tại sao tài liệu không cụ thể (chính xác) về điều này? Nó sẽ là tốt hơn để nói: e == null? e2 == null: e.compareTo (e2) == 0) – user3038094

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