我有以下内容:
fruitMap.remove(fruitId, fruitProperties);
fruitMap是:
private Map<FruitId, FruitProperties> fruitMap = new HashMap<FruitId, FruitProperties>();
当我尝试构建我的代码时,我得到了一个:
ERROR
The method remove(Object) in the type Map<MyImplementation.FruitId, FruitProperties>
is not applicable for the arguments (Map<MyImplementation.FruitId, FruitProperties>)
问题是什么?
请注意,thiis调用是在我的“FruitImplementation”类中的方法“removeFruit()”内。
答案 0 :(得分:7)
来自the Javadocs:
对于此地图,默认实现等效于:
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.remove(key);
return true;
} else
return false;
默认实现不保证此方法的同步或原子性属性。提供原子性保证的任何实现都必须覆盖此方法并记录其并发属性。
所以你可以使用那个默认实现。把它放在一个静态帮助方法中也许。
但是如果这应该是线程安全的,你可能需要添加一些同步代码(或考虑使用ConcurrentMap,顺便说一下,自从Java 5以来已经有了remove方法)。
答案 1 :(得分:2)
您必须自己测试该值:
if(fruitProperties.equals(fruitMap.get(fruitId)) {
fruitMap.remove(fruitId);
}
注意,我的实现假设您正在测试非null fruitProperties
对象。
答案 2 :(得分:2)
remove(key, value)
方法会删除key
的条目(如果它当前已映射到value
)。该方法是在Java 1.8中添加的。 Map
接口的Javadoc提到了以下默认实现:
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.put(key, newValue);
return true;
} else
return false;
由于Objects
类仅在Java 1.7中添加,因此对于Java 1.6,您必须自己编写相等性测试。因此,如果您不需要方法的返回值,则可以将map.remove(key, value)
替换为:
if (map.containsKey(key) {
Object storedValue = map.get(key);
if (storedValue == null ? value == null : storedValue.equals(value)) {
map.remove(key);
}
}
请注意,这不是线程安全的。如果从多个线程访问映射,则必须添加同步块。
答案 3 :(得分:1)
如果您的值不能为null
if (fruitProperties.equals(fruitMap.get(fruitId))
fruitMap.remove(fruitId);
注意:为了保证线程安全,您需要将其包装在synchronized
块中。
答案 4 :(得分:1)
以下是完整的解决方案,处理synchronization
以及null
值等特定情况。
synchronized (fruitMap)
{
if ((fruitMap.containsKey(fruitId) // The key is present
&& (
(fruitProperties == null && fruitMap.get(fruitId) == null) // fruitProperties is null, so is the stored value
|| (fruitProperties != null && fruitProperties.equals(fruitMap.get(fruitId)))
)
)
{
fruitMap.remove(fruitId);
}
}
它适用于Java 6,它相当于:
fruitMap.remove(fruitId, fruitProperties);
答案 5 :(得分:1)
Objects.equals有这样的实现:
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
因此,删除的默认实现:
if (map.containsKey(key) && Objects.equals(map.get(key), value)) {
map.remove(key);
return true;
} else
return false;
可以用Java 6编写为:
if (map.containsKey(key) && ((map.get(key) == value) || (map.get(key) != null && map.get(key).equals(value)))) {
map.remove(key);
return true;
} else
return false;
答案 6 :(得分:1)
根据Java Doc,删除(对象键,对象值)
仅在当前映射时删除指定键的条目 到指定的值。
如果你的equals()被正确定义,你可以做这样的事情
FruitProperties valueFromMap = map.get(key);
if(valueFromMap != null){
if( valueFromMap == originalValue || valueFromMap.equals(originalValue)){
map.remove(key);
}
}
现在您正在使用简单的HashMap,我假设您通过同步或将其更改为ConcurrentHashMap来处理线程安全:)