在什么情况下,如果正确实现了hashCode和equals(),下面的代码会返回false吗?
myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next())
答案 0 :(得分:7)
尽管hashCode
是“确定性的”,但我可以想到的最可能的情况是,它可能基于可变字段。如果您在将hashCode
放入Map
之后更改用于计算{{1}}的字段,那么您将无法再找到它。
编辑:应该澄清你'通常'将无法再找到它。偶尔它仍然可以工作,因为两个数字仍然可以重新进入相同的存储桶。当然,这只会在发生这种情况时增加混乱!
答案 1 :(得分:3)
我看到的每个哈希算法都是“确定性的”,因为对于给定的一组输入值,你得到相同的哈希值。
如果基于对象的可变属性计算哈希码,则哈希码将在哈希映射中更改后,如果任何可变属性发生更改。
答案 2 :(得分:2)
目前尚不清楚“确定性”是什么意思,但是在将密钥插入哈希映射后,对密钥的任何哈希变化突变很容易产生这种影响。
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>
的哈希码是确定性的,但这并不意味着如果列表内容发生变化,它就不会改变。
答案 3 :(得分:2)
如果hashCode()
基于可变的实例属性,并且在插入后更改了这些属性,则迭代期间的hashCode()
调用将返回某些内容不同。 equals()
应基于这些相同的属性,预计也会失败。
当另一个帖子在迭代过程中从Map
删除了所有下一个项时,将不再有next()
。
我不会使用hashCode()
值作为键,我希望你自己使用对象。
答案 4 :(得分:1)
如果您的hashCode
和equals
彼此不一致,则可能会返回false。例如,如果equals
方法始终返回false
,则返回false
,因为没有任何对象可以比较等于地图中的键。
希望这有帮助!
答案 5 :(得分:0)
您可能希望先检查hasNext()。
答案 6 :(得分:0)
您可以在获取第一个密钥和调用containsKey之间删除另一个线程中的第一个密钥。