Why am I getting duplicate keys in Java HashMap?
<p>I seem to be getting duplicate keys in the standard Java HashMap.  By "duplicate", I mean the keys are equal by their <code>equals()</code> method.  Here is the problematic code:</p>

<pre><code>import java.util.Map;
import java.util.HashMap;

public class User {
    private String userId;
    public User(String userId) { 
        this.userId = userId;
    }
    public boolean equals(User other) {
        return userId.equals(other.getUserId());
    }
    public int hashCode() {
        return userId.hashCode();
    }
    public String toString() {
        return userId;
    }

    public static void main(String[] args) {
        User arvo1 = new User("Arvo-Part");
        User arvo2 = new User("Arvo-Part");
        Map&lt;User,Integer&gt; map = new HashMap&lt;User,Integer&gt;();
        map.put(arvo1,1);
        map.put(arvo2,2);

        System.out.println("arvo1.equals(arvo2): " + arvo1.equals(arvo2));
        System.out.println("map: " + map.toString());
        System.out.println("arvo1 hash: " + arvo1.hashCode());
        System.out.println("arvo2 hash: " + arvo2.hashCode());
        System.out.println("map.get(arvo1): " + map.get(arvo1));
        System.out.println("map.get(arvo2): " + map.get(arvo2));
        System.out.println("map.get(arvo2): " + map.get(arvo2));
        System.out.println("map.get(arvo1): " + map.get(arvo1));
    }
}
</code></pre>

<p>And here is the resulting output:</p>

<pre><code>arvo1.equals(arvo2): true
map: {Arvo-Part=1, Arvo-Part=2}
arvo1 hash: 164585782
arvo2 hash: 164585782
map.get(arvo1): 1
map.get(arvo2): 2
map.get(arvo2): 2
map.get(arvo1): 1
</code></pre>

<p>As you can see, the <code>equals()</code> method on the two <code>User</code> objects is returning <code>true</code> and their hash codes are the same, yet they each form a distinct <code>key</code> in <code>map</code>.  Furthermore, <code>map</code> continues to distinguish between the two <code>User</code> keys in the last four <code>get()</code> calls.</p>

<p>This directly contradicts the <a href="https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#get-java.lang.Object-" rel="nofollow noreferrer">documentation</a>:</p>

<blockquote>
  <p>More formally, if this map contains a mapping from a key k to a value v such that (key==null ? k==null : key.equals(k)), then this method returns v; otherwise it returns null. (There can be at most one such mapping.)</p>
</blockquote>

<p>Is this a bug?  Am I missing something here?  I'm running Java version 1.8.0_92, which I installed via Homebrew.</p>

<p>EDIT: This question has been marked as a duplicate of this <a href="https://stackoverflow.com/questions/26850095/java-1-7-override-of-hashcode-not-behaving-as-i-would-expect">other question</a>, but I'll leave this question as is because it identifies a seeming inconsistency with <code>equals()</code>, whereas the other question assumes the error lies with <code>hashCode()</code>.  Hopefully the presence of this question will make this issue more easily searchable.</p>