如何将Java 8 map.remove转换为Java 1.6?

时间:2015-01-17 00:05:17

标签: java

我有以下内容:

     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()”内。

7 个答案:

答案 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来处理线程安全:)