据我了解,以下代码应打印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")));
}
}
有人可以帮我理解这种行为吗?
答案 0 :(得分:55)
您实际上遇到过JDK中的错误,请参阅JDK-8178355。 IdentityHashMap
没有通过默认方法添加到remove(K,V)
的{{1}}方法的自定义实现,这会导致此问题。
答案 1 :(得分:30)
你把“A”,新的“B”
你删除“A”,新的“B”
所以,是的,您认为此IdentityHashMap应不删除该值看起来正确。
但是您使用的是 base AbstractMap中的remove(key, value)
方法 - 这个特定的子类不覆盖了它!
所以,虽然javadoc说:
此类使用哈希表实现Map接口,在比较键(和值)时使用引用相等性代替对象相等。
(和值)部分(可能)仅针对插入键/值对实现。
所以,重要的部分又来自javadoc:
这个类不是通用的Map实现!虽然这个类实现了Map接口,但它故意违反了Map的一般契约,它要求在比较对象时使用equals方法。此类仅适用于需要引用相等语义的极少数情况。
我的(可能是固执己见的)外卖:这堂课是一件非常特别的事。它有一个非常明确,狭隘的目的。你找到了一个分崩离析的例子。 (我并不感到惊讶:当你“改变”语义但决定重用现有代码时,几乎不可避免地遇到这种不一致的情况。)
可以被视为错误;而另一个答案证实:它是bug!