Я пытаюсь использовать HashSet, используя свой собственный класс «Inner» в качестве типа ключа, как показано ниже:
import java.util.HashSet;
class Inner {
int i;
String s;
public Inner(int i, String s) {
this.i = i;
this.s = s;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object o) {
Inner inner = (Inner) o;
return i == inner.i && s.equals(inner.s);
}
}
public class testEquals {
public static void main(String [] args) {
HashSet<Inner> hi = new HashSet<>();
hi.add(new Inner(1,"abc"));
System.out.println(hi.contains(new Inner(1,"abc")));
}
}
Он печатает "ложь"
(1) Мой вопрос в том, что пока я пытаюсь использовать функцию «содержит», мне приходится создавать новый объект из «внутреннего» класса для запроса, но поскольку это новый объект, hashcode () отличается. Поэтому я всегда получаю «ложь» для функций «содержит».
(2) Если я изменю hashCode () так, чтобы он возвращал «true», например, equals, когда значения одинаковы, тогда в других сценариях ссылки на разные объекты рассматриваются как «==», как одна уникальная ссылка.
(1) и (2) кажутся противоречащими друг другу.
Как это решить?
Спасибо!




Вы должны переопределить hashCode таким образом, чтобы два одинаковых объекта имели одинаковый hashCode.
Например:
@Override
public int hashCode() {
return Objects.hash(i,s);
}
Я не уверен, в чем ваша проблема с (2). Если два объекта равны согласно equals(), HashSet должен рассматривать их как идентичные объекты, даже если это не так.
Если, с другой стороны, вы хотите, чтобы HashSet рассматривал любой экземпляр Inner как уникальный (независимо от значений его переменных экземпляра), просто не переопределяйте hashCode и equals. Однако редко бывает полезно использовать HashSet без отмены этих методов.
hashCode(), не нарушая контракт равных хэш-кодов.The contract between equals() and hashCode() is:
- If two objects are equal, then they must have the same hash code.
- If two objects have the same hash code, they may or may not be equal.
hashCode() не возвращает истину, он возвращает значение типа int. Поэтому просто убедитесь, что он возвращает одно и то же значение int для двух разных объектов, чей equals() возвращает true.