2009-04-27 18 views
7

Tôi muốn tạo lớp học có thể sử dụng được trong SortedSet | SortedMap.Liệu nó có ý nghĩa đối với equals và compareTo không phù hợp?

class MyClass implements Comparable<MyClass>{ 
    // the only thing relevant to comparisons: 
    private final String name; 

    //... 
} 

Các phiên bản của lớp phải được sắp xếp theo thuộc tính tên của chúng.
Tuy nhiên, tôi không muốn các trường hợp được đặt tên giống nhau được coi là bằng nhau.

Vì vậy, một nội dung SortedSet trông giống như a, a, a, b, c.
(Thông thường, SortedSet sẽ chỉ cho phép a, b, c)

Trước hết: là này (triết học) phù hợp?

Nếu có, tôi có phải mong đợi hành vi không thể đoán trước được không, khi tôi không ghi đè equals(...)hashCode()?

Edit:
Tôi xin lỗi, câu hỏi của tôi dường như không phù hợp:
Tôi muốn đặt nhiều "bình đẳng" giá trị bên trong một thiết, mà không cho phép này bằng khái niệm.
Vì vậy, vui lòng không trả lời câu hỏi của tôi nữa.
Nhờ tất cả những ai đã trả lời.

+0

Tại sao không chỉ sử dụng một loại Bộ sưu tập khác? –

+0

Có, google-collection-API MultiSet | MultiMap có vẻ tốt cho việc này. Tôi hy vọng rất nhiều rằng Sun, aehm, Oracle guys một ngày nào đó sẽ thêm chức năng vào API thu thập Java ... –

Trả lời

18

Hãy để tôi hỏi bạn một câu hỏi: có ý nghĩa khi có a.compareTo(b) trả lại 0 và a.equals(b) trả lại false?

Thay vào đó, tôi sẽ sử dụng số Comparator<MyClass>. Đây là lý do tại sao tất cả các triển khai SortedMap/SortedSet mà tôi biết cho phép bạn chuyển vào một lúc Comparator khi tạo.

+0

Tôi sẽ có xu hướng trả lời: nó không có ý nghĩa;) Cảm ơn bạn, tôi quên rằng có những thứ như một so sánh;) –

+0

Câu hỏi đúng. – Joshua

2

Effective Java khuyến cáo rằng nếu bạn không thực hiện compareTo phù hợp với equals bạn nên ghi rõ như vậy:

Ngôn ngữ đề nghị là "Lưu ý: Lớp này có trật tự tự nhiên mà không phù hợp với chiều sâu. "

0

Chỉ cần đặt mã này trong các phương pháp bằng và anh không bao giơ suy nghĩ về nó một lần nữa:

public boolean equals(Object obj) { 
    if (this == obj) return true; 
    if (!(obj instanceof MyClass)) return false; 
    return 0 == this.compareTo((MyClass) obj); 
} 
+0

Nhưng nếu bạn thực hiện equals(), bạn phải triển khai hashcode(). Nếu không những điều kỳ lạ có thể xảy ra. –

+0

Bạn có thể ủy quyền hashCode cho một số thuộc tính khác hoặc phương thức trả về giá trị int có thể so sánh. Nhưng đừng bận tâm, vì hashCode giống như kiểm tra nếu nó là một tham chiếu tương tự, không phải nếu chúng có cùng giá trị. – Azder

4

Từ Javadoc cho đương

Nó được khuyến khích mạnh mẽ (mặc dù không bắt buộc) rằng thứ tự tự nhiên là phù hợp với bằng.Đây là quá vì sắp xếp bộ (và sắp xếp bản đồ) mà không cần bộ so sánh rõ ràng xử "lạ" khi chúng được sử dụng với yếu tố (hoặc phím) mà trật tự tự nhiên là không phù hợp với bằng

Nếu bạn muốn có compareTo không nhất quán với equals(), bạn nên sử dụng một bộ so sánh rõ ràng bằng cách cung cấp một lớp thực hiện Comparator.

Nếu có, tôi có phải chờ đợi hành vi không thể đoán trước được không, khi tôi không ghi đè bằng (...) và hashcode()?

Bạn vẫn nên ghi đè bằng() và hashcode(). Có hoặc không bằng() và hashcode() nhất quán với compareTo là một vấn đề khác.

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