JDK-6584544 : (coll) Wrong Set.add(E) method implementation in HashSet
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2007-07-24
  • Updated: 2012-10-08
  • Resolved: 2007-07-24
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
1.6.0_02, 1.5.0_11, 1.5.0_12 and other

A DESCRIPTION OF THE PROBLEM :
According to Set.add() method description (http://java.sun.com/javase/6/docs/api/java/util/Set.html#add(E)), new element is added to the set "if the set contains no element e2  such that (e==null ? e2==null : e.equals(e2))".
HashSet, at the same time, uses hashCode() method to check for equality, not equals(), as it should. This leads to some confusing. The other variant is to change documentation.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the following code. If you uncomment the hashCode() method, you'll get what expected (1).


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.HashSet;
import java.util.Set;

public class TestClass {
    public static void main(String[] args) {
    
        MyClass c1 = new MyClass();
        c1.setId(1);
        
        MyClass c2 = new MyClass();
        c2.setId(1);
        
        Set<MyClass> s = new HashSet<MyClass>();
        s.add(c1);
        s.add(c2);
        
        System.out.println(s.size());
    }


}

class MyClass {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    
    public boolean equals(Object obj) {
        return id == ((MyClass) obj).id;
    }
    
    /*
    public int hashCode() {
        return id;
    }
    */
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
It is necessary to override a hashCode() method so that it corresponds equals(), besides, it is a recommended practice to override this method.

Comments
EVALUATION Seems like a duplicate of 6579200. Wording should be added to the collections that use hashCode to clarify that hashCode must obey Object.hashCode contract, and must not change while resident in the collection.
24-07-2007