java - AbstractMap 重写 hashcode 存在问题

标签 java dictionary hashcode

在仔细阅读 Java 中 AbstractMap 的源代码时,我遇到了这个:

440      /** 
441       * Returns the hash code value for this map.  The hash code of a map is 
442       * defined to be the sum of the hash codes of each entry in the map's 
443       * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt> 
444       * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two maps 
445       * <tt>m1</tt> and <tt>m2</tt>, as required by the general contract of 
446       * {@link Object#hashCode}. 
447       * 
448       * <p>This implementation iterates over <tt>entrySet()</tt>, calling 
449       * {@link Map.Entry#hashCode hashCode()} on each element (entry) in the 
450       * set, and adding up the results. 
451       * 
452       * @return the hash code value for this map 
....  
456       */ 
457      public int hashCode() { 
458      int h = 0; 
459      Iterator<Entry<K,V>> i = entrySet().iterator(); 
460      while (i.hasNext()) 
461          h += i.next().hashCode(); 
462      return h; 
463      }

这很有趣,因为它(看似意外)以哈希码的方式排除了某些内容。

如果此方法按编写的方式工作,则它会阻止使用哈希码,这些哈希码加在一起时会超过 Integer.MAXINT。如果您正在编写自己的哈希码,您可能想了解这一点。

我可以想到至少一个有用的哈希码定义,它可能与此发生冲突,而且它似乎对 HashMap 中的数据量很敏感。具体来说,map中的数据越多,entrySet越大,hashcode的运行总和就越大。

这看起来确实是一个没有记录的副作用,而且只是一个简单的旧主意。其目的似乎是利用加法交换律 (a+b == b+a) 来生成具有相同条目的映射所需的相等性,但是哇,这是一个多么糟糕的实现。

这需要任何人重写哈希码——即任何不想要仅仅对象实例品牌平等的人(==即大多数人),来了解他们不能或不太可能知道的事情。第一个是它们的哈希码的累积和(谁想到过这个??),另一个是将输入到 map 中的项目的最大数量以及这如何影响累积和。

这只是乱七八糟的。有人有任何见解吗?如果重要的话,hashcode() 是从 Object 类派生的。

最佳答案

intwrap around / overflow因此,上面 Integer.MAX_VALUE 不会抛出异常或导致问题。

这里的主要概念是,hashCode 应该为被认为相同的对象(在程序的特定运行中)产生相同(整数)值。此代码满足该要求。

请注意,哈希码冲突偶尔会发生,也就是说,在覆盖哈希码时,您始终需要提供有意义的equals覆盖。

关于java - AbstractMap 重写 hashcode 存在问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11071673/

上一篇:java图像卷积

下一篇:java - 类似的子类

相关文章:

c# - 不可能在字典中返回 IEnumerable 的子类型

java - 在散列函数中使用 << 和 >>>

java - 为什么这个方法在另一个方法完成之前运行?

java - OSGi 和性能?

java - 应用程序关闭时清理 JSF session 范围 bean

javascript - d3 voronoi arc Map - 控制.arcs的属性

Python排序多个属性

algorithm - 33 字节的错误检测码,检测前 32 字节翻转的位

java - Java HashMap 如何处理具有相同哈希码的不同对象?

java - 带有进度监听器的 GWT FileUpload