IdentityHashMap返回不正确的值

时间:2017-06-21 09:14:54

标签: java

据我了解,以下代码应打印false,因为它正在进行基于identity的比较。

但是,当我运行以下代码时,它正在打印true

public class Test1 {
  public static void main(String[] args) {
    IdentityHashMap m = new IdentityHashMap();
    m.put("A", new String("B"));
    System.out.println(m.remove("A", new String("B")));
  }
}

有人可以帮我理解这种行为吗?

2 个答案:

答案 0 :(得分:55)

您实际上遇到过JDK中的错误,请参阅JDK-8178355IdentityHashMap没有通过默认方法添加到remove(K,V)的{​​{1}}方法的自定义实现,这会导致此问题。

答案 1 :(得分:30)

“A”,新的“B”

删除“A”,新的“B”

所以,是的,您认为此IdentityHashMap应删除该值看起来正确。

但是您使用的是 base AbstractMap中的remove(key, value)方法 - 这个特定的子类覆盖了它!

所以,虽然javadoc说:

  

此类使用哈希表实现Map接口,在比较键(和值)时使用引用相等性代替对象相等。

(和值)部分(可能)仅针对插入键/值对实现。

所以,重要的部分又来自javadoc:

  

这个类不是通用的Map实现!虽然这个类实现了Map接口,但它故意违反了Map的一般契约,它要求在比较对象时使用equals方法。此类仅适用于需要引用相等语义的极少数情况。

我的(可能是固执己见的)外卖:这堂课是一件非常特别的事。它有一个非常明确,狭隘的目的。你找到了一个分崩离析的例子。 (我并不感到惊讶:当你“改变”语义但决定重用现有代码时,几乎不可避免地遇到这种不一致的情况。)

可以被视为错误;而另一个答案证实:它是bug