2014-03-01 42 views
2

我想有一個Set < Map <Character, Integer> >實例。但是我不能用new HashSet < HashMap<Character, Integer> >實例化它。如何在java中正確地實例化一組映射?

我必須要麼將其更改爲

Set<HashMap<Character, Integer>> v = new HashSet<HashMap<Character, Integer>>(); 

Set<Map<Character, Integer>> v = new HashSet<Map<Character, Integer>>(); // I prefer this one 

誰能告訴我,爲什麼Java的不能轉換HashSet<HashMap<Character, Integer>>Set<Map<Character, Integer>>

+1

下面的答案是正確的,但它不是在您的情況確實有關 - 你爲什麼要希望把實際的實現類的您想在泛型簽名中使用的Map?由於Java 7有可能寫也迴避這個問題更短的方式你的任務:'設置<地圖<字符,整數>> V =新的HashSet <>();' –

回答

4

向您展示相同的情況會更簡單 - 我們使用ObjectString代替Map<Character, Integer>HashMap<Character, Integer>

假設我們可能Set<Object> set = new HashSet<String>();。那麼這段代碼必須是有效的:

HashSet<String> strings = new HashSet<String>(); 
HashSet<Object> objects = strings; 
objects.add(new Object()); // Not a string! 

String firstString = strings.iterator().next(); // Bang! 

您是否看到這裏出了什麼問題?一組字符串是不是一組對象,因爲你可以添加任何對象一組對象,而一組字符串可以只有包含字符串。

一旦你得到了你的頭一輪,將它移植回你更復雜的情況:一個Set<HashMap<Character, Integer>>只能包含HashMap<Character, Integer>元素......而與Set<Map<Character, Integer>>你可以添加任何種Map<Character, Integer>。所以他們不兼容。

+0

我明白了。感謝您的回答。 –

3

泛型不是協變。

允許使用標準的例子。你上課

class Fruit{} 
class Apple extends Fruit{} 
class Bababa extends Fruit{} 

如果創建了水果

Set<Fruit> myFruits 

設置你應該通過它的Set<Fruit>,不Set<Apple>Set<Banana>實例。

這是爲什麼?想想看,通過myFruits引用您將能夠存儲任何類型的水果組,所以這將是確定讓你通過Apple如果引用存放設定的Banana S'

這就是爲什麼如果你聲明Set<Map<whatever>類型的引用它只能容納這意味着可以容納各種Map S,而不僅僅是HashMaps實例。

所以

Set<Map<Character, Integer>> v3 = new HashSet<Map<Character, Integer>>(); 
// ^^^          ^^^ 

這個泛型類型必須是TE攻方