2013-01-14 86 views
2

我經常有Comparator類型,而我需要Comparable,反之亦然。是否有可重複使用的JDK API相互轉換?沿着線的東西:將Comparable從Comparable轉換爲Comparable?

public static <C> Comparable<C> toComparable(final Comparator<C> comparator) { 
     // does not compile because Hidden can not extend C, 
     // but just to illustrate the idea 
     final class Hidden extends C implements Comparable<C> { 
      @Override 
      public int compareTo(C another) { 
       return comparator.compare((C) this, another); 
      } 
     }; 
     return new Hidden(); 
    } 

    public static <C extends Comparable<C>> Comparator<C> toComparator(final Class<C> comparableClass) { 
     return new Comparator<C>() { 
      @Override 
      public int compare(C first, C second) { 
       assert comparableClass.equals(first.getClass()); 
       assert comparableClass.equals(second.getClass()); 
       return first.compareTo(second); 
      } 
     }; 
    } 

回答

3

ComparableComparator從阿帕奇百科全書集合似乎爲解決Comparable<T>Comparator問題(可惜它不是一般類型友好)。

反向操作不太可能,因爲Comparator<T>代表算法,而Comparable<T>代表實際數據。你需要某種組合。快速而骯髒的解決方案:

class ComparableFromComparator<T> implements Comparable<T> { 

    private final Comparator<T> comparator; 
    private final T instance; 

    public ComparableFromComparator(Comparator<T> comparator, T instance) { 
     this.comparator = comparator; 
     this.instance = instance; 
    } 

    @Override 
    public int compareTo(T o) { 
     return comparator.compare(instance, o); 
    } 

    public T getInstance() { 
     return instance; 
    } 
} 

說你有類Foo不是Comparable<Foo>但你必須Comparator<Foo>。您可以使用這樣的:

Comparable<Foo> comparable = new ComparableFromComparator<Foo>(foo, comparator); 

正如你所看到的(尤其是沒有混入),這是非常醜陋(我甚至不知道它會工作...)還要注意,comparable不延長Foo,您必須改爲撥打.getInstance()

+1

對於仿製藥友好的實現,番石榴的['Ordering.natural()'](http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/ common/collect/Ordering.html#natural())的作品,並且有很多額外的功能。 –

0

我不認爲你們真的可以在它們之間進行轉換,也不是真的有意義,因爲Comarable是類本身的屬性,而Comparator是外部類。

最好的辦法是寫某種包含基礎比較邏輯(也可能有實現Comparator)實用類的,然後使用這個類作爲Comparable實現類本身邏輯的一部分。

+1

不是真的,'toComparator'起作用,它是另一個'Comparable'這個棘手的問題。 –

1

可比項目可以進行排序,因爲他們有一個compareTo

Collection<Comparable> items; 
Collections.sort(items); 

如果項目可比,他們需要一個比較對象做比較:

Collections<T> items; 
Collections.sort(items, comparator); 

橋接比較是微不足道的,你已經做到了。

將每個T item包裝在一些帶比較器的Comparable適配器中,似乎沒有用處。 首先不是繼承,但作爲領域需要包裝項目。

public class CatorComparable<T> implements Comparable<CatorComparable<T>> { 
    public T value; 
    private Comparator<T> cator; 

    public CatorComparable(T value, Comparator<T> cator) { 
     this.value = value; 
     this.cator = cator; 
    } 

    @Override 
    public int compareTo(CatorComparable<T> other) { 
     return cator.compareTo(value, other.value); 
    } 
} 

開銷太大。

+0

對於大多數Java JDK來說你是對的,但是有專用庫需要其中一個或另一個,然後開發人員最終編寫轉換樣板代碼。 –

2

自從Java 8以來,Comparator接口添加了一些實用程序默認方法,可幫助從可比較的數據庫中獲取比較器。

請考慮以下名稱按用戶排序的示例。

class Person { 
    String firstName; 
    String lastName; 
} 

List<Person> people = ... 
people.sort(Comparator.comparing(Person::firstName)); 
相關問題