2017-10-28 114 views
1

我實現了一個基於兩個類型參數<K,V>的地圖,其中K是關鍵類型,而V是值類型。爲什麼這些類型不是分配兼容的,我如何定義一個賦值兼容類?

public class Map<K,V> implements Map<K,V> 
{ .. implementation .. } 

Map接口中的一種方法返回一組映射條目。

public Set<java.util.Map.Entry<K,V>> entrySet() 

由於我的地圖的實現是基於AVL樹,另一個類必須實現爲Set<MapNode>

public class EntrySet<K,V> implements Set<MapNode<K,V>> 
{ .. implementation ..} 

爲了告訴大家,地圖樹的節點的確映射條目,它們是定義如下:

public class MapNode<K,V> implements Map.Entry<K,V> 
{ .. implementation .. } 

的entrySet所以包含相同的樹作爲Map本身,而是把該樹節點作爲元素集合(其這就是爲什麼它必須單獨實施)。

在地圖上實現的方法,返回一套條目,因此應如下所示:

/* (non-Javadoc) 
* @see java.util.Map#entrySet() 
*/ 
@Override 
public Set<java.util.Map.Entry<K,V>> entrySet() 
{ 
    return new EntrySet<K,V>(this.comparator,this.tree); 
} 

然而,編譯器給了我以下錯誤:

「類型不匹配:不能轉換從EntrySet<K,V>Set<Map.Entry<K,V>>

我的問題:

  • 我的以下假設是否正確? (或者,如果沒有,是什麼問題?)

一套Map.Entry<K,V>必須能夠包含的Map.Entry<K,V>所有排序,不只是MapNode<K,V>對象。因此,在邏輯上不是EntrySet<K,V> a Set<Map.Entry<K,V>,並且因此這兩種集合類型不被認爲是分配兼容的。

  • 是否有任何其他的方式來定義一個類EntrySet<K,V>,基於相同的樹結構(我做希望通過創建或調用其他的數據結構,以增加運行時間),使得這個類的一個對象可以無論何處需要Set<Map.Entry<K,V>

更新:

我曾嘗試以下版本:

public class EntrySet<K,V> implements Set<MapNode<K,V>> 
{ .. implementation ..} 

在這種情況下,迭代器創建一個類似的問題。存在即整齊地遍歷整棵樹的迭代器類,但它被定義爲一個超類的MapNode<K,V>的迭代,而這個迭代器不能轉換爲所需Iterator<Map.Entry<K,V>>

@Override 
public Iterator<Map.Entry<K,V>> iterator() 
{ 
    // this iterator type can not be cast to the desired return type 
    return new TreeNodeIterator<MapNode<K,V>,K>(this.tree); 
} 

我可能複製整個迭代器代碼並粗暴地使用它在一個新的,獨立的迭代類,但我更喜歡更優雅的解決方案。

所以我仍然卡在這裏。

更新:

在平均時間,我已經創造了另一個獨立的迭代器類,盒原來迭代器,並相應地轉換「下一個」元素。這並不是很優雅,但至少它現在可行。不過,任何更優雅的解決方案都將非常受歡迎!

回答

1

Why are these types not assignment compatible?

的問題是,Map::entrySet()簽名說,它應該返回一組任何Map.Entry<K,V>對象。但是您返回的對象僅支持對象爲MapNode的條目。

的(概念)的原因,這是一個問題,是一個Set允許插入以及取出元件,並且所述Set<java.util.Map.Entry<K,V>>::add(...)應該能夠任何Map.Entry<K,V>添加到該集合。但是您的EntrySet實施的簽名不會允許這樣做。

我建議你試試這個:

public class EntrySet<K,V> implements Set<? extends Map.Entry<K,V>> 
    { .. implementation ..} 

或本

public class EntrySet<K,V> implements Set<Map.Entry<K,V>> 
    { .. implementation ..} 
+0

感謝我的假設的確認。至於解決方案的想法 - 我只是試了一下,編譯器告訴我「超類型可能沒有指定任何通配符」。 – BlondMammuth

+0

試試另一個。 –