2010-04-13 54 views
9

例如當第二個對象被添加到TreeSet時,下面的代碼拋出一個ClassCastException異常。無法編寫TreeSet以便類型參數只能是Comparable類型? TreeSet不會編譯,因爲Object是不可比較的。這種方式實際上是他們的工作 - 類型安全。爲什麼Java的TreeSet沒有指定它的類型參數必須擴展Comparable?

import java.util.TreeSet; 
public class TreeSetTest { 
    public static void main(String [] args) { 
    TreeSet<Object> t = new TreeSet<Object>(); 
    t.add(new Object()); 
    t.add(new Object()); 
    } 
} 

回答

4

如果類型必須是Comparable,則無法創建具有非可比較類型和Comparator的TreeSet(您可以像現在這樣)。

解決這個問題的一種方法仍然是類型安全的,它將有兩個類:一個具有可比較的類型參數,另一個具有非可比較類型參數並且沒有默認構造函數(只有構造函數需要Comparator ),但我想java開發人員不想引入兩個基本上做同樣事情的類(儘管可以很容易地將其實現爲另一個包裝)。另一種(也可以說是更乾淨的方式)將擴展類型系統,以便某些構造函數只在與某些類型參數一起使用時才存在(即,如果類型參數可比較,則僅存在默認構造函數),但是我想這會已經使java的通用系統過於複雜。

+0

感謝您的全面回答。大聲笑,我認爲通用系統已經夠複雜了! – Tarski 2010-04-13 19:22:42

13

TreeSet不需要其類型參數爲Comparable,因爲它可以採取外部Comparator用於比較非Comparable值。

+0

啊謝謝。我想沒有辦法指定對無參數構造函數的限制,以便它只能使用可比較對象?是否有更好的設計有兩個類 - 一個採用Comparable類型參數,另一個採用任何類型參數,但構造函數必須採用Comparators? – Tarski 2010-04-13 19:12:30

+4

@Tarski:'TreeSet'在1.2中添加。泛型在1.5中加入。 – 2010-04-13 19:25:54

1

這是因爲值而不是必然必須執行Comparable。您可以明確傳遞一個Comparator對象,在這種情況下,元素類型不需要是Comparable

0

您還可以使用Comparator作爲構造函數參數創建一個TreeSet。那麼你的物品不必是可比的。

相關問題