title: hashCode implementation strategies
body: <p>Some major JVM classes (such as <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode%28%29" rel="nofollow">String</a> or <a href="http://docs.oracle.com/javase/6/docs/api/java/util/List.html#hashCode%28%29" rel="nofollow">List implementations</a>) implement equals by returning <code>Σ 31^n * field_n.hashCode()</code> for every <code>field_n</code> that is relevant for the <code>equals</code> method. Beside, this approach is recommended by Joshua Bloch in Effective Java (item 9).</p>
  
  <p>However, other classes such as <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Map.Entry.html#hashCode%28%29" rel="nofollow"><code>Map.Entry</code> implementations</a> follow different rules. For example, the Map.Entry documentation states that the hash code of a <code>Map.Entry</code> should be</p>
  
  <pre><code> (e.getKey()==null   ? 0 : e.getKey().hashCode()) ^
   (e.getValue()==null ? 0 : e.getValue().hashCode())
  </code></pre>
  
  <p>This can sometimes be impractical to use in hash tables, since:</p>
  
  <ul>
  <li>the hash code of all entries which have the same key and value is 0,</li>
  <li>two entries e1 and e2 so that e1.key = e2.value and e1.value = e2.key have the same hash code.</li>
  </ul>
  
  <p>Why did Java choose this implementation specification for <code>Map.Entry</code> hashCode instead of, for example, <code>31 * (e.getKey()==null   ? 0 : e.getKey().hashCode()) + (e.getValue()==null ? 0 : e.getValue().hashCode())</code>?</p>
  
  <p><strong>Edit 1:</strong></p>
  
  <p>To help figure out the problem, here is an example of useful code where the result has very poor performance due to hash collisions if many entries have the same key and value.</p>
  
  <p>This method computes the frequencies of the entries of different maps (using Guava's Multiset).</p>
  
  <pre><code>public static &lt;K, V&gt; Multiset&lt;Map.Entry&lt;K, V&gt;&gt; computeEntryCounts(
          Iterable&lt;Map&lt;K, V&gt;&gt; maps) {
      ImmutableMultiset.Builder&lt;Map.Entry&lt;K, V&gt;&gt; result = ImmutableMultiset.builder();
      for (Map&lt;K, V&gt; map : maps) {
          for (Map.Entry&lt;K, V&gt; entry : map.entrySet()) {
              result.add(entry);
          }
      }
      return result.build();
  }
  </code></pre>