2010-06-02 35 views
5

Tôi có một phương thức cần Comparator cho một trong các tham số của nó. Tôi muốn chuyển một số điện thoại Comparator thực hiện việc so sánh bình thường và một số so sánh đảo ngược làm ngược lại.So sánh trực tiếp trong Java ra khỏi hộp

java.util.Collections cung cấp reverseOrder() điều này là tốt để so sánh ngược lại, nhưng tôi không thể tìm thấy bất kỳ thông thường Comparator.

Giải pháp duy nhất trong đầu tôi là Collections.reverseOrder(Collections.reverseOrder()). nhưng tôi không thích nó bởi vì phương pháp kép gọi bên trong.

Dĩ nhiên tôi có thể viết một NormalComparator như thế này:

public class NormalComparator<T extends Comparable> implements Comparator<T> { 
    public int compare(T o1, T o2) { 
     return o1.compareTo(o2); 
    } 
} 

Nhưng tôi thực sự ngạc nhiên rằng Java không có một giải pháp cho điều này ra khỏi hộp.

Trả lời

6

Hầu hết những nơi mà bạn có thể chỉ định một Comparator cũng có một phiên bản mà không cần sử dụng một Comparator ở tất cả trong trường hợp này nó sử dụng trật tự tự nhiên (tức là nó hy vọng tất cả các đối tượng để thực hiện Comparable và sử dụng compareTo).

Vì vậy, giải pháp thông thường cho điều này là không chỉ định Comparator. Bạn có trường hợp cụ thể chỉ hỗ trợ cách tiếp cận Comparator không?

Nếu bạn hoàn toàn cần nó, Google Collections (cũng như Guava, mà là một superset của bộ sưu tập của Google) cung cấp Ordering.natural() trả về a Ordering object đại diện cho trật tự tự nhiên theo quy định của giao diện Comparable. Ordering thực hiện Comparator, vì vậy bạn có thể chỉ cần sử dụng điều đó.

+0

Đó là phương pháp của tôi để nó không có thứ tự tự nhiên. thực sự nó có, bởi vì tôi đã viết nó để làm việc, nhưng tôi không muốn, tôi đang tìm kiếm một giải pháp đẹp hơn) –

+0

Và có, tôi đã viết nó bởi vì tôi đã tìm nguồn gốc của 'HashTree'. –

+0

@KARASZI: 'HashTree' là bạn đang nói về? Không có lớp như vậy trong Java SE.Bạn có nghĩa là' TreeMap'? –

0

Đối ngược lại sử dụng đặt hàng Collections.reverseOrder() ...

Trả về một so sánh mà áp đặt ngược lại của trật tự tự nhiên trên một bộ sưu tập các đối tượng thực hiện các giao diện Comparable.

+0

bạn không hiểu câu hỏi. Tôi cũng muốn trực tiếp, không chỉ ngược lại. Việc đảo ngược đôi có thể là bình thường –

+0

@ István: Đối với tự nhiên đặt hàng thực hiện đơn giản NaturalComparator cho các đối tượng Comparable. Tôi không thể tìm thấy một trong thư viện chuẩn. –

+0

đó là trong OP, như bạn có thể thấy –

0

thường không cần thiết cho một trật tự tự nhiên Comparator<T>, vì thường có một tình trạng quá tải mà phải mất một Comparable<T>. Bạn luôn có thể làm theo các ví dụ thiết lập bởi Collections.reverseOrder() và viết một cái gì đó như thế này:

private static final Comparator<?> NATURAL_ORDER = 
    new Comparator<Comparable<Object>>() { 
    @Override public int compare(Comparable<Object> o1, Comparable<Object> o2) { 
     return o1.compareTo(o2); 
    } 
    }; 

@SuppressWarnings("unchecked") 
public static <T> Comparator<T> naturalOrder() { 
    return (Comparator<T>) NATURAL_ORDER; 
} 

Sau đó bạn có thể viết một cái gì đó như:

List<String> names = Arrays.asList("Bob", "Alice", "Carol"); 
Collections.sort(names, naturalOrder()); 
System.out.println(names); 
// prints "[Alice, Bob, Carol]" 
+0

như bạn có thể thấy trong OP, đó là những gì tôi đã làm! –

1

Nhưng tôi thực sự ngạc nhiên rằng Java không có một giải pháp cho điều này ra khỏi hộp.

Tôi cho rằng nó sẽ hữu ích trong một vài trường hợp ... như của bạn. Nhưng trong hầu hết trường hợp sử dụng, một ứng dụng sẽ chỉ sử dụng phương thức compareTo của đối tượng trực tiếp.Gián tiếp qua một đối tượng Comparator sẽ không phục vụ mục đích ... hầu hết thời gian.

Tôi đoán là các nhà thiết kế của các API Java này đã không xem xét trường hợp sử dụng của bạn đủ quan trọng để hỗ trợ trực tiếp. Bên cạnh đó, việc triển khai của bạn chỉ là bốn dòng mã.

Thư viện lớp Java không hoàn hảo. Học cách sống với nó :-).

+0

Và chúng chấp nhận một 'null' trong mọi phương thức mà một' Comparator' là cần thiết (và chúng dán phương thức 'compareTo' thay vì tạo một' NaturalComparator' mới), vì vậy không thực sự là một giải pháp ** DRY **. tôi nghĩ ... –