Неправильное переопределение метода 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, также это уловят, но это не для всех.)