Java 为什么我们需要检查哈希代码两次?

Java 为什么我们需要检查哈希代码两次?,java,dictionary,hashcode,Java,Dictionary,Hashcode,这是HashMap.java(docjar)的代码。第431行计算密钥的哈希。这有助于获取第432行上的索引i。这意味着该索引中的所有条目都应该具有相同的散列。为什么在第440行再次检查哈希相等(如果(e.hash==hash) private void putForCreate(K键,V值){ 430 int hash=(key==null)?0:hash(key.hashCode()); 431 int i=indexFor(散列,table.length); 432 433

这是HashMap.java(docjar)的代码。第431行计算密钥的哈希。这有助于获取第432行上的索引i。这意味着该索引中的所有条目都应该具有相同的散列。为什么在第440行再次检查哈希相等<代码>(如果(e.hash==hash)

private void putForCreate(K键,V值){
430 int hash=(key==null)?0:hash(key.hashCode());
431 int i=indexFor(散列,table.length);
432
433           /**
434*查找密钥的预先存在的条目。对于
435*克隆或反序列化。只有在
436*输入映射是排序映射,其排序不一致,w/等于。
437            */
438 for(条目e=表[i];e!=null;e=e.next){
439对象k;
440如果(e.hash==hash&&
441((k=e.key)==key | |(key!=null&&key.equals(k))){
442 e.价值=价值;
443人返回;
444               }
445           }
446
447 createEntry(散列、键、值、i);
448       }

同一个bucket可能包含其键具有不同哈希代码的条目(因为bucket索引
i
是通过在计算的哈希上应用模数
表。长度
来确定的,因此不同的哈希代码可能映射到同一个bucket),因此第440行中的比较省去了为两个没有相同哈希代码的键调用
equals
,这通常比比较两个
int
s更昂贵。

哪个版本的Java?OpenJDK 8中没有
putForCreate
。一个bucket可以容纳两个不同的哈希代码吗???@Rehman是的,它可以。假设HashMap有16个bucket。那么hashcode 3和19都将映射到同一个bucket-3。你确定吗?我不这么认为。那么hashcode如何确定bucket呢?“密钥的哈希代码是235->这对密钥存储在bucket编号235中”。
private void putForCreate(K key, V value) {
  430           int hash = (key == null) ? 0 : hash(key.hashCode());
  431           int i = indexFor(hash, table.length);
  432   
  433           /**
  434            * Look for preexisting entry for key.  This will never happen for
  435            * clone or deserialize.  It will only happen for construction if the
  436            * input Map is a sorted map whose ordering is inconsistent w/ equals.
  437            */
  438           for (Entry<K,V> e = table[i]; e != null; e = e.next) {
  439               Object k;
  440               if (e.hash == hash &&
  441                   ((k = e.key) == key || (key != null && key.equals(k)))) {
  442                   e.value = value;
  443                   return;
  444               }
  445           }
  446   
  447           createEntry(hash, key, value, i);
  448       }