Я переопределил методы hashCode
и equals
, как показано ниже, и хочу понять реализацию метода get Map.
public class Student{
String name;
Student(String s){
this.name = s;
}
@Override
public boolean equals(Object o) {
return false;
}
@Override
public int hashCode() {
return 111;
}
public static void main(String[] args) {
Map<Student,String> map=new HashMap<>();
Student ob1=new Student("A");
Student ob2=new Student("B");
map.put(ob1,"A");
map.put(ob2,"B");
System.out.println(map.get(ob1));
}
}
Я попробовал запустить map.get()
, ожидая null
результата, потому что ключ никогда не будет найден, потому что метод equals()
всегда будет возвращать false, но в этом случае я получаю результат как A
.
HashMap
get
проверяет равенство с помощью == перед использованием равенства.
Таким образом, тот факт, что вы используете тот же объект, который использовали в качестве ключа (а не объект с тем же содержимым, но с другой ссылкой), заставляет get
работать.
Если вы попробуете этот способ
public static void main(String[] args) {
Map<Student,String> map=new HashMap<>();
Student ob1=new Student("A");
Student ob2=new Student("B");
Student keyTest = new Student("A");
map.put(ob1,"A");
map.put(ob2,"B");
System.out.println(map.get(keyTest)); //different key here
}
он печатает null
.
Интересно, что в стандартной equals
реализации для каждого значения, хешированного с конкретным "bucket"
, эти значения обычно проверяются дважды на ссылочное равенство, пока не будет найдено совпадение. Один раз в реализации карты и один раз в равных.
Напоминаем, что другие реализации карты или аналогичной структуры данных могут с самого начала полагаться на равенство. Итак, сначала проверьте равенство ссылок. Т.е.
if (o == name) return true;