在什么情况下,只要正确实现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()
基于mutable的实例属性,并且在插入后更改了这些属性,则迭代期间的hashCode()
调用将返回不同的内容。并且equals()
应该基于这些相同的属性,并且也会失败。
当另一个线程在迭代过程中从Map
中删除所有next项时,将不再有next()
。
我不会将hashCode()
值用作键,我会把对象本身作为对象。
如果您的hashCode
和equals
彼此不同意,则可能返回false。例如,如果equals
方法始终返回false
,则将返回false
,因为没有任何对象可以与映射中的键进行比较。
希望这会有所帮助!
您可能想先检查hasNext()。
您可以在获取第一个键和调用containsKey之间的另一个线程中删除第一个键。