2013-02-25 46 views
3

我試圖創建一個類,可以將其與相同類的實例進行比較,也可以創建一個類到StringJava與實例或字符串類似

例如,請考慮以下幾點:

public class Record implements Comparable<Record> { 
    public String name; 

    public Record(String name) { 
     this.name = name; 
    } 

    public int compareTo(Record o) { 
     return name.compareTo(o.name); 
    } 
} 

我再放入一個ArrayList這個如下:

ArrayList<Record> records = new ArrayList<Record>(); 
records.add(new Record("3")); 
records.add(new Record("1")); 
records.add(new Record("2")); 

如果我再對它們進行排序,它們是正確排序:

​​

但是,我不希望能夠通過基於字符串的二進制搜索來獲得記錄。例如:

int index = Collections.binarySearch(records, "3"); 

的問題是,有沒有compareTo方法,需要一個String作爲參數,而我不能確定如何實現它。

我試着這樣做:

public class Record implements Comparable<Record>, Comparable<String> { 
    public String name; 

    public Record(String name) { 
     this.name = name; 
    } 

    public int compareTo(Record o) { 
     return name.compareTo(o.name); 
    } 

    public int compareTo(String o) { 
     return name.compareTo(o); 
    } 
} 

但是,當然,你無法實現根據不同的參數不止一次相同的接口。

所以,我正在尋找一種方法來做到上述。我查看了以前的以下答案,但沒有找到真正能夠充分回答的答案。至少,如果有的話,我不明白。

基本上,我想要做的是以下幾點:

public int compare(Record r, String s) { 
    return r.name.compareTo(s); 
} 

據我所知,雖然你不能比較不同類型的對象而沒有實現某種通用接口或超類。 String我真的沒有這個選擇。

有人可以告訴我如何做到這一點,如果有可能?謝謝。

UPDATE 我知道我可以做到以下幾點:

Collections.binarySearch(records, new Record("3")); 

但是,這不是我後。謝謝。

+1

在Java中,你總是** **都有一個共同的超類,'Object' 。 – 2013-02-25 19:41:44

+0

@PatriciaShanahan如果我使用「可比較的」,是否不允許與除「String」或「Record」之外的對象進行比較? – crush 2013-02-25 19:42:34

+0

是int包含int那**始終**列表? – skuntsel 2013-02-25 19:44:26

回答

4

您可以實現Comparable而不需要使用類型進行限定,並使用instanceof檢查傳入Object,並根據您接收的類型來執行不同的行爲。

+0

如果它不是預期的類型,我應該拋出異常嗎? – crush 2013-02-25 19:43:06

+1

是的,根據可比較的API,如果它不是預期的類型,拋出一個ClassCastException – 2013-02-25 19:44:02

0

定義接口ComparableToString並實現它有一些問題嗎?它的compareTo方法可以將調用者限制爲String。沒有instanceof,不需要鑄造。

public class Record implements Comparable<Record>, ComparableToString 
    { 
     public String name; 

     public Record(String name) 
     { 
      this.name = name; 
     } 

     public int compareTo(Record o) 
     { 
      return name.compareTo(o.name); 
     } 

     public int compareTo(String o) 
     { 
      return name.compareTo(o); 
     } 
    } 
    interface ComparableToString 
    { 
     public int compareTo(String s); 
    } 
+0

你能提供一個你的意思嗎? – crush 2013-02-25 19:47:29

+0

'Collections.binarySearch(記錄,「3」);'不適用於這個例子。我已經嘗試過了。我收到錯誤:類型集合中的binarySearch(List <?extends Comparable >,T)方法不適用於參數(ArrayList ,String)' – crush 2013-02-25 19:52:02

+0

是的,這不適用於* extended *問題 - 爲你的原始「我試圖創建一個類,可以比較相同的類的實例,或字符串。」,它確定。但是你也想把結果類提供給將要使用Comparable接口的東西,而這不會處理它。 – arcy 2013-02-25 20:05:08

1

你不能那樣做。 從javadoc中

It follows immediately from the contract for compareTo that the quotient is an equivalence relation on C and String's compareTo will never return true for your Record.

你可以做什麼,是建立比較會比較字符串和記錄。只是把它放在沒有泛型的地方。

+0

同樣來自javadoc:'強烈建議(儘管不要求)自然順序與equals相等。「 – 2013-02-25 20:03:58

1

你可以嘗試下爲獲得該指數的排序集合中:

class Record implements Comparable<String> { 

    public String name; 

    public Record(String name) { 
     this.name = name; 
    } 

    @Override 
    public int compareTo(String o) { 
     return name.compareTo(o); 
    } 

} 

和:

public static void main(String[] args) { 

    ArrayList<Record> records = new ArrayList<Record>(); 
    records.add(new Record("3")); 
    records.add(new Record("1")); 
    records.add(new Record("2")); 

    Collections.sort(records, new Comparator<Record>() { 
     @Override 
     public int compare(Record a, Record b) { 
      return a.name.compareTo(b.name); 
     } 
    }); 

    int index = Collections.binarySearch(records, "3"); 
    System.out.println(index); // 2 

} 
+0

因此,我沒有定義自定義的」比較器「,而是將其設置爲」Comparable 「,而不是將其設置爲」Comparable 「 。這不是一個壞主意。我猜想,我可以通過在我的Record類的'public Comparator getComparator(){}'方法中封裝新的Comparator (){}'來進一步實現。 – crush 2013-02-25 20:12:59

相關問題