2012-04-25 29 views
6

này được thực hiện như sau (jdk1.6.0_31):Java: về thực hiện bộ sưu tập ReverseComparator

private static class ReverseComparator<T> 
implements Comparator<Comparable<Object>>, Serializable { 

// use serialVersionUID from JDK 1.2.2 for interoperability 
private static final long serialVersionUID = 7207038068494060240L; 

    public int compare(Comparable<Object> c1, Comparable<Object> c2) { 
     return c2.compareTo(c1); 
    } 

    private Object readResolve() { return reverseOrder(); } 
} 

Tại sao không thể thay nó được thực hiện như sau:

private static class ReverseComparator<T extends Comparable<T>> 
implements Comparator<T>, Serializable { 

// use serialVersionUID from JDK 1.2.2 for interoperability 
private static final long serialVersionUID = 7207038068494060240L; 

    public int compare(T c1, T c2){ 
     return c2.compareTo(c1); 
    } 
    ... 
} 

Là nó chỉ phong cách hoặc có lý do nào sâu hơn không?

EDIT: mã nguồn được hiển thị là từ Sun/Oracle jdk ((jdk1.6.0_31)).

+0

Mã này ở đâu chính xác? Tôi không tìm thấy nó trong JDK, nhưng có rất nhiều nơi khác. Không có gì cho đến nay thậm chí sử dụng Generics. –

+0

Tôi tìm thấy nó trong jdk1.6.0_31, src.zip. – shrini1000

+0

Nhưng bạn có thể cho tôi biết chính xác địa điểm không? Bên trong lớp nào? –

Trả lời

1

Tôi tin rằng tất cả đều liên quan đến ý định tạo ra một đối tượng đơn lẻ ReverseComparator. Vì cá thể singlenton phải được định nghĩa trong một bối cảnh tĩnh nên không có điểm nào trong việc sử dụng bất kỳ kiểu generic nào.

static final ReverseComparator REVERSE_ORDER = new ReverseComparator(); 

Mã này, tạo cảnh báo kiểu thô.

Như vậy, việc thực hiện ReverseComparator, chỉ được sử dụng cho vấn đề này, có thể đã được như bạn đề xuất hoặc khi nó được triển khai. Có lẽ họ đã chọn thực hiện hiện tại vì nó dễ đọc hơn, và bởi vì họ nghĩ rằng khái quát hóa hơn nữa là không cần thiết nếu nó chỉ là riêng được sử dụng cho mục đích đơn giản này.

Chạy trình giải mã Java trong quá trình triển khai của bạn và trong quá trình triển khai của Oracle tạo ra cùng một mã byte loại thô.

public int compare(java.lang.Comparable, java.lang.Comparable 
public int compare(java.lang.Object, java.lang.Object); 

Cuối cùng, khi so sánh được tiếp xúc thông qua giao diện công cộng của lớp Collections trong phương pháp reverseOrder(), nó là không thể tránh được đúc và các cảnh báo không được kiểm soát. Nhưng tất cả chúng ta chắc chắn rằng điều này không thể thất bại, bất kể các loại có liên quan.

Tóm lại, IMHO Tôi nghĩ lý do duy nhất tại sao nó được thực hiện vì nó phải liên quan đến sự rõ ràng của mã, hoặc với mong muốn không làm phức tạp những thứ cần thiết nếu, dù sao, cảnh báo không được kiểm soát không thể ngăn chặn được . Nhưng này, đây không phải là lần đầu tiên tôi sai ;-)

+0

Tôi đồng ý với bạn rằng việc khái quát hóa thêm là không cần thiết vì lớp học được sử dụng riêng tư. Trong thực tế, tôi không nghĩ rằng việc khái quát hóa điều này là có thể bởi vì không có lớp nào trong Java đủ chung để thực hiện Comparable để nó có thể được sử dụng như một đối số kiểu trong một kiểu tham số hóa. Vì vậy, cảm giác của tôi là, giống như một phần còn lại không cần thiết từ một số mã trước đó. – shrini1000

1

Chỉ cần đoán, nhưng nó được lưu trữ trong một lĩnh vực tĩnh

static final ReverseComparator REVERSE_ORDER 
      = new ReverseComparator(); 

nên phiên bản của bạn sẽ tạo ra một cảnh báo 'loại thô'.

+0

Vâng, tôi cũng nhận được cảnh báo đó với ReverseComparator của Java (vì nó khai báo 'T' trong định nghĩa của nó) nếu tôi sao chép-dán lớp đó vào lớp của tôi và khởi tạo nó một cách tĩnh. – shrini1000

+0

Hmm, trong nguồn của tôi nó chỉ là 'lớp tĩnh riêng ReverseComparator' (không có' T') – artbristol

+0

là nó jdk1.6.0_31 hoặc một số phiên bản khác? – shrini1000

1

Tôi đang xem Oracle 1.6.0_26, nhưng tôi thấy cùng một mã. Theo như tôi có thể nói, đó là những chức năng tương đương. Bạn cũng có thể có khả năng viết nó như thế này:

private static class ReverseComparator<T> implements Comparator<Comparable<T>>, Serializable { 

    // use serialVersionUID from JDK 1.2.2 for interoperability 
    private static final long serialVersionUID = 7207038068494060240L; 

    public int compare(Comparable<T> c1, Comparable<T> c2) { 
     return c2.compareTo((T) c1); 
    } 

    private Object readResolve() { 
     return reverseOrder(); 
    } 
} 

đoán duy nhất của tôi là tại sao họ đã làm nó bằng cách sử Comparable<Object> được dựa trên thực tế là các lớp học mà thực hiện Comparable (hoặc Comparator) nên tuân theo hợp đồng equals(), mà làm sử dụng Object. Vì vậy, ngữ nghĩa, điều này nhấn mạnh rằng kết nối. Ngoài ra, tôi không thể nghĩ ra lý do tại sao.

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