在什么情况下,给定hashCode和equals((的正确实现,下面的代码可以返回false吗?
myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next())
我能想到的最有可能的情况是,即使hashCode
是"确定性的",它也可能基于可变字段。 如果在将hashCode
放入Map
后更改用于计算的字段,那么您将无法再找到它。
编辑:应该澄清你"通常"将无法再找到它。 有时它仍然有效,因为两个数字仍然可以重新组合到同一个存储桶中。 当然,这只会在它发生时增加混乱!
我见过的每个哈希算法都是"确定性的",因为对于一组给定的输入值,你会得到相同的哈希值。
如果哈希代码是基于对象的可变属性计算的,则哈希代码在进入哈希映射后(如果更改了任何这些可变属性(,哈希代码将更改。
目前还不清楚你所说的"确定性"是什么意思,但是在将密钥插入哈希映射后,任何对密钥进行哈希更改的突变都很容易产生这种效果。
import java.util.*;
public class Test {
public static void main(String[] args) {
List<String> strings = new ArrayList<String>();
Map<List<String>, String> map = new LinkedHashMap<List<String>, String>();
map.put(strings, "");
System.out.println(map.containsKey(map.keySet().iterator().next())); // true
strings.add("Foo");
System.out.println(map.containsKey(map.keySet().iterator().next())); // false
}
}
ArrayList<T>
的哈希代码是确定性的,但这并不意味着如果列表的内容发生变化,它不会改变。
-
如果
hashCode()
基于可变的实例属性,并且这些属性在插入后发生更改,则迭代期间的hashCode()
调用将返回不同的内容。并且equals()
应该基于这些相同的属性,预计也会失败。 -
当另一个线程在迭代过程中从
Map
中删除了所有后续项目时,将不再有next()
。
我不会将hashCode()
值用作键,我会使用对象本身。
如果你的hashCode
和equals
彼此不一致,这可能会返回 false。 例如,如果 equals
方法总是返回 false
,这将返回 false
,因为没有任何对象可以与映射中的键进行比较。
希望这有帮助!
你可能想先检查hasNext((。
您可以在获取第一个密钥和调用 containsKey 之间删除另一个线程中的第一个密钥。