IdentityHashMap 返回的值不正确 - 为什么?

2022-09-01 08:06:58

据我所知,下面的代码应该像基于比较的那样打印。falseidentity

但是,当我运行以下代码时,它正在打印: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")));
  }
}

有人能帮助我理解为什么会这样吗?


答案 1

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


答案 2

“A”,新的“B”

删除“A”,新的“B”

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

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

所以,尽管javadoc说:

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

(和值)部分(可能)仅用于插入键/值对。

因此,重要的部分再次来自javadoc:

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

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

它可以被视为错误;正如另一个答案所证实的那样:这是一个错误