在阅读 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。如果您正在编写自己的哈希码,您可能想知道这一点。
我可以想到至少一个有用的哈希码定义可能会与此冲突,而且它似乎对哈希图中的数据量很敏感。具体来说,map中的数据越多,entrySet越大,hashcode的运行总和也越大。
这似乎真的是一个无证的副作用,也只是一个普通的老坏主意。其目的似乎是利用加法交换律 (a+b == b+a) 来产生具有相同条目的映射所需的相等性,但是哇,多么糟糕的实现啊。
这需要任何覆盖哈希码的人——即任何不想要仅仅对象实例品牌平等的人(== 即大多数人),知道他们不能或不可能知道的事情。第一个是它们的哈希码的累积总和(谁曾想到过这个??),另一个是将输入到地图中的最大项目数以及如何影响累积总和。
这只是乱七八糟的。任何人有任何见解?hashcode() 派生自类 Object 如果它很重要。