title: HashSet allows duplicate item insertion if hashCode() is not overridden
body: <pre><code>class temp {
  int id;
  
  public int getId() {
    return id;
  }
  
  temp(int id) {
    this.id = id;
  }
  
  public void setId(int id) {
    this.id = id;
  }
  
  @Override
  public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    temp other = (temp) obj;
    if (id != other.id)
        return false;
    return true;
  }
  }
  
  public class testClass {
  
      public static void main(String[] args) {
        temp t1 = new temp(1);
        temp t2 = new temp(1);
        System.out.println(t1.equals(t2));
        Set&lt;temp&gt; tempList = new HashSet&lt;temp&gt;(2);
        tempList.add(t1);
        tempList.add(t2);
        System.out.println(tempList);
  }
  </code></pre>
  
  <p>The program adds both the elements to the Set. I was shocked at first because while adding methods to set, equals method is invoked.</p>
  
  <p>But then I overrode the hashCode method: </p>
  
  <pre><code>@Override
      public int hashCode() {
          final int prime = 31;
          int result = 1;
          result = prime * result + id;
          return result;
      }
  </code></pre>
  
  <p>And then it did not add. This is surprising as the Javadoc of Set and add() method says that it checks only equals() while adding into the Set.</p>
  
  <p>And this is the javadoc for add():</p>
  
  <pre><code>/**
       * Adds the specified element to this set if it is not already present.
       * More formally, adds the specified element &lt;tt&gt;e&lt;/tt&gt; to this set if
       * this set contains no element &lt;tt&gt;e2&lt;/tt&gt; such that
       * &lt;tt&gt;(e==null&amp;nbsp;?&amp;nbsp;e2==null&amp;nbsp;:&amp;nbsp;e.equals(e2))&lt;/tt&gt;.
       * If this set already contains the element, the call leaves the set
       * unchanged and returns &lt;tt&gt;false&lt;/tt&gt;.
       *
       * @param e element to be added to this set
       * @return &lt;tt&gt;true&lt;/tt&gt; if this set did not already contain the specified
       * element
       */
      public boolean add(E e) {
        return map.put(e, PRESENT)==null;
      }
  </code></pre>
  
  <p>Then I realized that the HashSet is implemented as a HashMap and in the map, the hashCode of the object is used as the key. So, it is treating them using different keys if you dont override hashCode.</p>
  
  <p>Shouldn't this be in the documentation of the add() method or that of HashSet?</p>