Неправильное переопределение метода equals для hashSets в Java

У меня есть следующий код:

public class Trooper {
private String name;
private boolean mustached;
public Trooper(String name, boolean hasMustache) {
    this.name = name; this.mustached = hasMustache;
}
public String getName() { return name; }
public boolean hasMustache() { return mustached; }
public boolean equals(Trooper other) {
    if (this == other) return true;
    if (null == other || !(other instanceof Trooper)) return false;
    Trooper that = (Trooper) other;
    return this.name.equals(that.name) && this.mustached == that.mustached;
}
public int hashCode() { return 1; }
}

Затем выполняется следующее:

ArrayList<Trooper> troopers = new ArrayList<>();
troopers.add(new Trooper("Farva", true));
troopers.add(new Trooper("Farva", true));
troopers.add(new Trooper("Rabbit", false));
troopers.add(new Trooper("Mac", true));
Set<Trooper> trooperSet = new HashSet<>(troopers);

Почему следующий код возвращает false?

trooperSet.contains(new Trooper("Mac", true));

Я понимаю, как hashCode и equals используются в hashSet, когда вызывается метод содержит. Единственная причина, по которой я могу догадаться, что он возвращает false вместо true, заключается в том, что метод equals не был должным образом переопределен. Если по этой причине предыдущее утверждение возвращает false, то почему?

2 ответа

Вы перегружаете equals() метод, не переопределяя его. Вот в чем разница. Правильная подпись для equals() является:

public boolean equals(Object other) {
    ...
}

Ваш текущий equals() никогда не используется HashSet, Вместо, Object#equals() используется, отсюда и результат.

Кстати, в том числе @Override тег может помочь обнаружить эти ошибки.

Вы перегружаете метод equals(), а не переопределяете его.

Object.equals() определяется как: public boolean equals(Object obj) указав ваш аргумент в качестве типа Trooper вы определили подпись нового метода.

С использованием @Override аннотация действительно помогает отлавливать такие ошибки; аннотация предупредит вас, что вы ничего не отменяете. (Статические проверки в хорошей IDE, такой как IntelliJ, также это уловят, но это не для всех.)

Другие вопросы по тегам