Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hashset allows duplicates?

This question surely isn't a new one, but I didn't find any helpful answer anywhere.

As you can see in the code below, the equals and hashcode methods are overriden, but it still allows duplicates. The Hashcode has been generated automatically by Netbeans.

@Override
public boolean equals(Object o)
{
    TaskDetails other = (TaskDetails) o;
    if ( (id_subtask == other.id_subtask)
            && ((date.compareTo(other.date)) == 0) )
    {
        System.err.println("Duplicate Entry"+id_subtask+" + "+other.id_subtask);
        return true;
    }
    else
    {
        System.out.println("Good!" +id_subtask+" + "+other.id_subtask);
        return false;
    }

} 

@Override
public int hashCode() {
    int hash = 7;
    hash = 71 * hash + this.id_subtask;
    hash = 71 * hash + this.id_team_member;
    hash = 71 * hash + Float.floatToIntBits(this.nb_hours);
    hash = 71 * hash + (this.date != null ? this.date.hashCode() : 0);
    hash = 71 * hash + (this.comment != null ? this.comment.hashCode() : 0);
    hash = 71 * hash + (this.subtask_name != null ? this.subtask_name.hashCode() : 0);
    System.out.println("Hash : "+hash + "Subtask : " + id_subtask);
    return hash;       
}

This the code used to add an entry into the hashset :

TaskDetails newTaskDetails = new TaskDetails
                                (
                                    s.getId_subtask(),
                                    mus.teamMember.getId_team_member(),
                                    f,
                                    mysqlFormat.format(caldate),
                                    c.substring(0, Math.min(c.length(), 100)),
                                    s.getName_subtask()
                                );

                            allTasks.add(newTaskDetails);

(allTasks being the Hashset)

This code is used in function A and B.

If only function A is executed, it works fine. If function B is executed after function A (so the code above is executed twice), then the hashset suddenly accepts duplicates, even though system.err is triggered saying there is a duplicate entry?

Is there a flaw in the code, or am I just missing something?

Thanks for the help!

like image 321
Xaviraan Avatar asked Dec 10 '12 15:12

Xaviraan


2 Answers

you are using 2 fields to consider 2 objects to be "equal", but you are using more than 2 fields to construct the hashcode. your hashCode() method cannot be more specific than your equals() method. as a good rule of thumb, your hashCode() method should not use any fields that your equals() method does not use (it can use fewer however). to put it more technically, if 2 objects are "equal" they must have the same hashcode (the reverse is not required).

like image 151
jtahlborn Avatar answered Nov 16 '22 23:11

jtahlborn


You are violating the consistency requirement between hashCode() and equals(). If two objects are equal according to equals(), they must also have the same hash. Because your equals only considers two fields, and hashCode considers more, this requirement is not met.

like image 26
Jochen Avatar answered Nov 17 '22 00:11

Jochen