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を超えるハッシュコードを使用できなくなります。独自のハッシュコードを作成している場合は、これについて知りたいと思うかもしれません。
私はこれに反する可能性のあるハッシュコードの少なくとも1つの有用な定義を考えることができ、さらにそれはハッシュマップ内のデータの量に敏感であるように思われます。具体的には、マップ内のデータが多いほど、entrySetが大きくなり、ハッシュコードの現在の合計が大きくなります。
これは実際には文書化されていない副作用のようであり、単なる古い悪い考えでもあります。目的は、可換加算の法則(a + b == b + a)を利用して、同じエントリを持つマップの必要な等式を生成することであるように見えますが、すごい、なんて悪い実装でしょう。
これには、ハッシュコードをオーバーライドする人(つまり、オブジェクトインスタンスのブランドの平等(==つまりほとんどの人)だけを望まない人)が、知らない、または知る可能性が低いことを知る必要があります。1つはハッシュコードの累積合計(誰がこれを考えたことがありますか??)であり、もう1つはマップに入力されるアイテムの最大数であり、それが累積合計にどのように影響するかを示します。
これはいたずら書きです。誰か洞察がありますか?hashcode()は、重要な場合はクラスObjectから派生します。