Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This could happen if the <code>equals</code> method was asymmetric. Suppose there are two keys a and b such that:</p> <ul> <li><code>a.hashCode() == b.hashCode()</code></li> <li><code>a.equals(b)</code> returns false</li> <li><code>b.equals(a)</code> returns true</li> </ul> <p>Then suppose that the <code>HashMap</code> implementation searches for an existing key by calling <code>existingKey.equals(newKey)</code> for each existing key with the same hash code as the new key.</p> <p>Now suppose we originally add them in the order { a, b }.</p> <p>The first key (<code>a</code>) obviously goes in with no problems. The second key (<code>b</code>) insertion ends up calling <code>a.equals(b)</code> - which is false, so we get two keys.</p> <p>Now building the second <code>HashMap</code>, we may end up getting the entries in the order { b, a }.</p> <p>This time we add <code>b</code> first, which is fine... but when we insert the second key (<code>a</code>) we end up calling <code>b.equals(a)</code>, which returns true, so we <em>overwrite</em> the entry.</p> <p>That may not be what's going on, but it <em>could</em> explain things - and shows the dangers of an asymmetric <code>equals</code> method.</p> <p>EDIT: Here's a short but complete program demonstrating this situation. (The exact details of <code>a</code> and <code>b</code> may not be the same, but the asymmetry is.)</p> <pre><code>import java.util.*; public class Test { private final String name; public Test(String name) { this.name = name; } public static void main(String[] args) { Map&lt;Test, String&gt; firstMap = new HashMap&lt;Test, String&gt;(); Test a = new Test("a"); Test b = new Test("b"); firstMap.put(b, "b"); firstMap.put(a, "a"); Map&lt;Test, String&gt; secondMap = new HashMap&lt;Test, String&gt;(); for (Map.Entry&lt;Test, String&gt; entry : firstMap.entrySet()) { System.out.println("Adding " + entry.getKey().name); secondMap.put(entry.getKey(), entry.getValue()); } System.out.println(secondMap.size()); } @Override public int hashCode() { return 0; } @Override public boolean equals(Object other) { return this.name.equals("b"); } } </code></pre> <p>Output on my machine:</p> <pre><code>Adding a Adding b 1 </code></pre> <p>You may not get the output that way round - it depends on:</p> <ul> <li>The way that <code>equals</code> is called (<code>candidateKey.equals(newKey)</code> or vice versa)</li> <li>The order in which entries are returned from the set</li> </ul> <p>It may even work differently on different runs.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload