IdentityHashMap返回不正确的值

Jok*_*ker 33 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")));
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Pal*_*nal 54

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


Gho*_*ica 29

"A",新的"B"

删除 "A",新的"B"

所以,是的,你的假设,这IdentityHashMap应该删除该值看起来是正确的.

但是您正在使用基本 AbstractMap中的remove(key, value)方法- 该方法未被此特定子类覆盖!

所以,尽管javadoc说:

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

(和值)的部分是(可能)只为实现插入键/值对.

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

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

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

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

  • 所以在某种意义上这是一个实现错误 - 行为与此类的Javadoc描述不匹配. (6认同)