2017-07-14 90 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