title: Why won't my HashSet allow me to add two of the same instance, if their equals() says they're false?
body: <p><a href="http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add%28E%29" rel="nofollow">The documentation for <code>HashSet.add</code></a> says</p>
  
  <blockquote>
    <p>Adds the specified element to this set if it is not already present. More formally, adds the specified element e to this set if this set contains no element e2 such that (e==null ? e2==null : e.equals(e2)). If this set already contains the element, the call leaves the set unchanged and returns false.</p>
  </blockquote>
  
  <p>Since my code below will return false for <code>e.equals(e2)</code>, I'd expect it to let me add the same instance twice.  But the set only contains my instance once.  Can someone explain why?</p>
  
  <pre><code>package com.sandbox;
  
  import java.util.HashSet;
  import java.util.Set;
  
  public class Sandbox {
  
      public static void main(String[] args) {
          Set&lt;A&gt; as = new HashSet&lt;A&gt;();
          A oneInstance = new A();
          System.out.println(oneInstance.equals(oneInstance));    //this prints false
          as.add(oneInstance);
          as.add(oneInstance);
          System.out.println(as.size());  //this prints 1, I'd expect it to print 2 since the System.out printed false
      }
  
      private static class A {
          private Integer key;
  
          @Override
          public boolean equals(Object o) {
              if (!(o instanceof A)) {
                  return false;
              }
  
              A a = (A) o;
  
              if (this.key == null || a.key == null) {
                  return false;   //the key is null, it should return false
              }
  
              if (key != null ? !key.equals(a.key) : a.key != null) {
                  return false;
              }
  
              return true;
          }
  
          @Override
          public int hashCode() {
              return key != null ? key.hashCode() : 0;
          }
      }
  
  }
  </code></pre>