Objects are equal, hash codes are equal, HashSet contains one but not the other --- how?

I have a (immutable) object, Group, which I am trying to use in a HashSet. However, I get strange results:

// Position is another immutable class, GroupType is an enum
Group t1 = new Group(new Position(0, 0), GroupType.ROW);
Group t2 = new Group(new Position(0, 0), GroupType.ROW);
Set<Group> s = new HashSet<Group>();
s.add(t1);
System.out.format("t1.hashCode(): %d\nt2.hashCode(): %d\nt1.hashCode() == t2.hashCode(): %b\nt1.equals(t2): %b\nt2.equals(t1): %b\ns.contains(t1): %b\ns.contains(t2): %b\n",
    t1.hashCode(),
    t2.hashCode(),
    t1.hashCode() == t2.hashCode(),
    t1.equals(t2),
    t2.equals(t1),
    s.contains(t1),
    s.contains(t2)
    );

leads to the following:

t1.hashCode(): 486656595
t2.hashCode(): 486656595
t1.hashCode() == t2.hashCode(): true
t1.equals(t2): true
t2.equals(t1): true
s.contains(t1): true
s.contains(t2): false

t1 and t2 have the same hash codes, and equals () claims to be the same. How can a HashSet contain one and not the other?

(And no, none of these methods secretly modifies t1 or t2, repeating the print statement, gets the same results.)

Group.equals () is as follows:

public boolean equals(Group g2) {
    return (this.type.equals(g2.type)) && (this.basis.equals(g2.basis));
}
A type

is a (final) listing. base is a position that has the following meanings:

public boolean equals(Position pos) {
    return (x == pos.x) && (y == pos.y);
}

where x and y are internal finite variables.

However, I get the same results that replace it:

public boolean equals(Group g2) {
    return true;
}
+3
source share
2 answers

... , equals :

public boolean equals(Group other)

equals, HashSet. , :

@Override // Make the compiler check we're overriding something
public boolean equals(Object other)

:

Object o1 = t1;
Object o2 = t2;

System.out.println(o1.equals(o2));
System.out.println(o2.equals(o1));
+11

All Articles