我正在尝试创建一个 HashMap 版本,如果输入重复的键,它不会替换该值,而是实际上将两个相应的值添加在一起。键值必须是 Number
类型,以便可以进行添加。但是,它似乎不明白我的 V
是 Number
类型,或者至少在我尝试调用 super.put
之前它是这样的>。就好像 HashMap
中的 V
实际上与我声明的用于扩展 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);
}
}
最佳答案
不要创建在Map
方法中执行此操作的put
。 Map.put
method的合约是(强调我的):
Associates the specified value with the specified key in this map (optional operation). If the map previously contained a mapping for the key, the old value is replaced by the specified value. (A map m is said to contain a mapping for a key k if and only if m.containsKey(k) would return true.)
因此,您的 map 将违反界面的约定。
当然,您可以自由添加AdditiveMap.addValuesTogether
(或其他)方法。但您最好只使用现有的 merge
方法:
map.merge(key, newValue, v -> v + newValue);
这样做的主要优点是,相同的语法适用于所有数字类型(嗯,对于int
、long
、float
和double
;您需要对short
、char
和byte
,因为添加它们时它们会被扩展为int
;您可以使用v -> v += newValue
来避免显式强制转换;但实际上你不能做你想做的事情(如果不提供Merger<V>
策略,它可以将V
添加到另一个V
;与使用现有方法相比,这只是非常重量级的)。
关于java - 具有参数化集合的泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45111065/