java - 为什么我们需要检查两次哈希码?

标签 java dictionary hashcode

这是HashMap.java (docjar) 的代码。 key 的哈希值在第 431 行计算。这有助于在第 432 行获取索引 i。该索引处的所有条目都应具有相同的哈希值。为什么在第 440 行再次检查哈希相等性? (if (e.hash == hash )

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       }

最佳答案

同一个存储桶可能包含其键具有不同哈希码的条目(因为存储桶索引i是通过对计算出的哈希值应用模table.length来确定的,因此不同哈希码可能会映射到同一个存储桶),因此第 440 行中的比较使您无需为不具有相同哈希码的两个键调用 equals ,这通常会更多比比较两个 int 更昂贵。

关于java - 为什么我们需要检查两次哈希码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34119364/

相关文章:

json - swift 对象映射器 : toJSONString for a dictonary containing mappable Object

Java-如何从字符串列表创建哈希ID

java - 覆盖父类(super class) Equals 和 HashCode 并认为我应该对子类做同样的事情

java - ResponseEntity<Stream<MyObject>> 是否将所有内容都存储在内存中?

java - Spring Restful Webservice 上传 CSV

java - 使用 Scanner 对象的代码中的逻辑问题

java - 小对象池是否比 Android 的 Java 垃圾收集器更有效?

python - 是否可以查找某个数字下的字典值的键?

Python:从字典中获取最大的值

java - 测试重写的 equals 方法