对象相等,哈希码相等,HashSet包含一个但不包含另一个---怎么样?

时间:2011-03-21 19:48:02

标签: java hashset

我有一个(不可变的)对象Group,我试图在HashSet中使用它。但是,我得到了奇怪的结果:

// 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)
    );

导致以下结果:

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和t2具有相同的哈希码,而equals()声称它们是相同的。 HashSet如何包含一个而不包含另一个?

(不,这些方法都没有秘密修改t1或t2;重复print语句会获得相同的结果。)

Group.equals()如下:

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

type是存储的(最终)枚举。基础是一个位置,具有以下等于:

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

其中x和y是内部的最终变量。

但是,我得到了相同的结果:

public boolean equals(Group g2) {
    return true;
}

2 个答案:

答案 0 :(得分:11)

我怀疑......我的是你的equals方法看起来像这样:

public boolean equals(Group other)

这不会覆盖内置的equals方法,这是HashSet将使用的方法。确保您的equals方法是:

@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));

答案 1 :(得分:-2)

这是。它不会添加另一个与现有元素相等的元素。 http://download.oracle.com/javase/6/docs/api/java/util/Set.html#add%28E%29