2014-04-13 45 views
-1

我想寫能夠接受這兩個對象作爲參數中的任何一個的功能:接受不同的設置,實現作爲參數

private static TreeSet<String> TREESET = new TreeSet<String>(); 
private static HashSet<String> HASHSET = new HashSet<String>(); 

我已經嘗試過這樣的

public static void printSet(Set s) { 
    // 
} 

public static void printSet(Set<String> s) { 
    // 
} 

即使在調用時轉換集合,我也會得到一個錯誤。什麼是正確的方法來做到這一點?

更新1

我已經試過與不鑄件:

printSet(SET); 
printSet((Set) SET); 
printSet((Set<String> SET); 

更新2

錯誤:

Exception in thread "main" java.lang.ClassCastException: TreeSet cannot be cast to java.util.Set at HashTreeSetClient.main(HashTreeSetClient.java:34)

+1

你是如何調用該方法的?不要使用原始類型。 –

+0

使用'public static void printSet(Set s)' – Braj

+1

你沒有得到「一個錯誤」。您遇到特定的錯誤,並顯示特定的錯誤消息,指出問題出在哪裏以及在哪裏。不讀/張貼這個錯誤信息是你最大的錯誤。 –

回答

1

只要使用泛型即可。

public static <T> void printSet(Set<T> s) { 
    // 
} 

避免原始類型。


或只是Set<String> s正如別人所說。

public static void printSet(Set<String> s) { 
    // 
} 

Set是在該方法中接受實現該接口的每個類的接口。

+0

如果你知道你只有一個'Set ',我不認爲沒有把它放在方法簽名中的原因。 – Makoto

+0

如果他改變它會怎麼樣? –

+0

然後他違反了他自己的合同。從我讀到的OP的帖子中,合同是他將擁有'Set '。如果他沒有,那麼*然後*使用泛型將是更可取的。 – Makoto

0

我認爲你誤解了Set接口的用途。實現Set的任何類可以被認爲是,作爲 a Set

這就是爲什麼這些聲明是合法的:

Set<String> stringSet = new HashSet<>(); 
Set<String> treeSet = new TreeSet<>(); 

現在讓我們來考慮你的方法:

public static void printSet(Set<String> s) { 
    // logic 
} 

什麼這個方法告訴我的是,你不關心具體類型的Set你正在使用,但它實際上可以被認爲是一個Set

實際上,這意味着,這兩個方法調用是合法的:

printSet(TREESET); 
printSet(HASHSET); 

...那絕對沒有鑄造是必需的,因爲既TreeSetHashSet實現Set接口。

這是非常重要,但是,您的集合上的泛型類型參數匹配方法簽名。

這一點,例如,是行不通的:

HashSet<Integer> hashSet = new HashSet<>(); 
printSet(hashSet); // compilation error 

如果由於某種原因,你要接受它的任何泛型類型參數Set,你可以使用這個語法來實現這一目標:

public static void printSet(Set<?> s) { 
    // logic 
} 

?通配符類型。它隱含地擴展了Object,並且可以用來接受任何類型的泛型。

相關問題