Объекты равны, хэш-коды равны, HashSet содержит один, но не другой --- как? - PullRequest
3 голосов
/ 21 марта 2011

У меня есть (неизменный) объект 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));
}

Тип - это (окончательное) перечисление.Базой является позиция, которая имеет следующие значения:

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

, где x и y - внутренние, конечные переменные.

Однако я получаю те же результаты, заменяя их на:

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

Ответы [ 2 ]

11 голосов
/ 21 марта 2011

У меня есть подозрение ... мое предположение состоит в том, что ваш метод 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));
0 голосов
/ 21 марта 2011

это набор .он не будет добавлять другой элемент, который равен существующему элементу.http://download.oracle.com/javase/6/docs/api/java/util/Set.html#add%28E%29

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...