2008-09-12 15 views
18

tôi là chuyển đổi một ứng dụng để sử dụng Java 1.5 và đã tìm thấy các phương pháp sau đây:Tôi có thể chuyển đổi mã sau đây để sử dụng Generics?

/** 
    * Compare two Comparables, treat nulls as -infinity. 
    * @param o1 
    * @param o2 
    * @return -1 if o1<o2, 0 if o1==o2, 1 if o1>o2 
    */ 
    protected static int nullCompare(Comparable o1, Comparable o2) { 
    if (o1 == null) { 
     if (o2 == null) { 
     return 0; 
     } else { 
     return -1; 
     } 
    } else if (o2 == null) { 
     return 1; 
    } else { 
     return o1.compareTo(o2); 
    } 
    } 

Lý tưởng nhất là tôi muốn thực hiện phương pháp này mất hai so sánh áp cùng loại, là nó có thể chuyển đổi này và làm thế nào ?

Tôi nghĩ sau đây sẽ làm các trick:

protected static <T extends Comparable> int nullCompare(T o1, T o2) { 

nhưng nó đã thất bại trong việc thoát khỏi một cảnh báo trong IntelliJ "cuộc gọi không được kiểm soát để 'compareTo (T) là một thành viên của kiểu thô 'java .lang.Comparable" trên dòng:

return o1.compareTo(o2); 

Trả lời

21

Thay đổi nó để:

protected static <T extends Comparable<T>> int nullCompare(T o1, T o2) { 

Bạn cần điều đó vì Compara ble là một kiểu generic.

+0

Aargh! Tôi không thể tin rằng tôi đã đóng cửa –

+0

Việc này sẽ giúp mọi người đi đến. – jodonnell

+0

Bạn có chắc T mở rộng so sánh là đúng không? Có vẻ như T mở rộng So sánh sẽ chính xác hơn? – cletus

5

Dưới đây là một trường hợp kỳ lạ:

static class A { 
    ... 
} 

static class B extends A implements Comparable<A> { 
    public int compareTo(A o) { 
     return ...; 
    } 
} 

May mắn mã như một ở trên là hiếm, nhưng nullCompare() sẽ không hỗ trợ so sánh của Bs trừ khi nó được tuyên bố rằng tương đương có thể áp dụng cho T hay bất kỳ lớp cha đó:

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) { 

Mặc dù hầu hết mọi người sẽ không bao giờ hưởng lợi từ điều chỉnh trên, nó có thể hữu ích khi thiết kế API cho thư viện đã xuất.

0

Tôi không chắc rằng việc chung hóa phương pháp này có ý nghĩa. Hiện tại, phương thức hoạt động trên bất kỳ loại Comparable nào; nếu bạn genericize nó, bạn sẽ phải thực hiện nó (với chính xác cùng một mã) nhiều lần. Đôi khi có thể so sánh hai đối tượng không có tổ tiên chung và bất kỳ phiên bản chung nào sẽ không cho phép điều này.

Bằng cách thêm generics bạn sẽ không thêm bất kỳ sự an toàn nào vào mã; bất kỳ vấn đề an toàn nào sẽ xảy ra trong cuộc gọi đến compareTo. Những gì tôi sẽ đề nghị chỉ đơn giản là đàn áp các cảnh báo. Nó không thực sự cảnh báo bạn về bất cứ điều gì hữu ích.

2

Không thể chỉnh sửa vì vậy tôi phải đăng câu trả lời của mình.

Bạn cần khai báo tham số kiểu lồng nhau vì Comparable là generic.

protected static <T extends Comparable<? super T>> int nullCompare(T o1, T o2) { 

Xin lưu ý rằng So sánh <? siêu T>, làm cho linh hoạt hơn. Bạn sẽ thấy cùng một định nghĩa phương thức trên Collections.sort

public static <T extends Comparable<? super T>> void sort(List<T> list) { 
0

Để làm cho nó thậm chí còn tổng quát hơn, bạn thậm chí có thể cho phép nó hoạt động cho hai loại khác nhau. = P

/** 
    * Compare two Comparables, treat nulls as -infinity. 
    * @param o1 
    * @param o2 
    * @return -1 if o1&lt;o2, 0 if o1==o2, 1 if o1&gt;o2 
    */ 
    protected static <T> int nullCompare(Comparable<? super T> o1, T o2) { 
    if (o1 == null) { 
     if (o2 == null) { 
     return 0; 
     } else { 
     return -1; 
     } 
    } else if (o2 == null) { 
     return 1; 
    } else { 
     return o1.compareTo(o2); 
    } 
    } 
Các vấn đề liên quan