2017-07-14 101 views
0

我試圖創建一個版本的HashMap,如果輸入了一個重複的鍵,但不會替換該值,但實際上會將兩個對應的值一起添加。鍵值必須爲Number,以便可以進行添加。然而,它似乎並不理解我的VNumber類型,或者至少在我嘗試撥打super.put之前。就好像在HashMap與我聲明的extend Number不一樣V具有參數化集合的泛型?

這是怎麼回事?

public class AdditiveMap<K, V extends Number> extends HashMap<K, V> 
{ 
    @Override 
    public V put(final K key, final V value) 
    { 
     if (containsKey(key)) 
      // Second param Found 'Number', required 'V' 
      super.put(key, (Number)(get(key).intValue() + value.intValue())); 
     else 
      super.put(key, value); 
    } 
} 
+0

消息是說'Integer'與'V'不一樣,這當然是正確的。 –

+5

這是不是''合併'方法是在'Map'接口中設計的? –

+0

@OliverCharlesworth'V' extends Number – Hatefiend

回答

6

不要創建Map它做到這一點的方法put。該Map.put method的合同(重點煤礦):

將指定值與此映射中(可選操作)指定的鍵。如果地圖先前包含密鑰的映射,則舊值由指定值代替。 (當且僅當m.containsKey(k)將返回true時,映射m被認爲包含關鍵k的映射。)

因此,您的映射將違反接口的合約。

您當然可以自由添加AdditiveMap.addValuesTogether(或其他)方法。但是你最好關閉只是用現有的方法merge

map.merge(key, newValue, v -> v + newValue); 

這樣做的主要優點是,這個相同的語法適用於所有數字類型(當然,對於intlongfloatdouble,你」 d需要鑄造short,charbyte,因爲當你添加它們時,它們被擴展爲int;你可以通過使用v -> v += newValue)來避免顯式的轉換。但你實際上不能做你想做的事情(沒有提供Merger<V>策略,它可以將V添加到另一個V;與使用此現有方法相比,這只是非常重量級的)。

+0

謝謝你的解釋。我會用這種方法。你能告訴我爲什麼最初的這種方法很糟糕嗎?謝謝。 – Hatefiend