Equals и hashCode должны учитывать одинаковый набор полей Exam. Тогда examTwo заменит значение для ключа, равного examOne, и итоговый HashMap будет содержать три записи, включая null.
Правильное использование объектов‑ключей в HashMap
Equals и hashCode должны учитывать одинаковый набор полей Exam. Тогда examTwo заменит значение для ключа, равного examOne, и итоговый HashMap будет содержать три записи, включая null.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
В примере используется HashMap<Exam, String>, где в качестве ключей выступают экземпляры класса Exam. Необходимо реализовать корректный механизм сравнения объектов Exam, чтобы HashMap правильно обрабатывала повторяющиеся ключи.
import java.util.HashMap;
import java.util.Map;
public class JetbulbInterview {
public static void main(String[] args) {
Map<Exam, String> exams = new HashMap<>();
Exam examOne = new Exam(1, "04.07.2021", 10);
Exam examTwo = new Exam(1, "04.07.2021", 10);
Exam examThree = new Exam(3, "04.07.2021", 9);
exams.put(null, "Zero");
exams.put(examOne, "One");
exams.put(examTwo, "Two");
exams.put(examThree, "Three");
exams.forEach((k, v) -> {
System.out.println("Key: " + k);
System.out.println("Value: " + v);
});
}
}
class Exam {
long id;
String date;
int mark;
public Exam(long id, String date, int mark) {
this.id = id;
this.date = date;
this.mark = mark;
}
@Override
public String toString() {
return "Exam{" +
"id=" + id +
", date='" + date + '\'' +
", mark=" + mark +
'}';
}
}
Ответ
Equals и hashCode должны учитывать одинаковый набор полей Exam. Тогда examTwo заменит значение для ключа, равного examOne, и итоговый HashMap будет содержать три записи, включая null.
Внутри Exam:
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
Exam e = (Exam) other;
return id == e.id && mark == e.mark && java.util.Objects.equals(date, e.date);
}
@Override
public int hashCode() {
return java.util.Objects.hash(id, date, mark);
}
Значения итоговых записей: Zero для null, Two для экзамена с id=1 и Three для id=3. Порядок обхода не гарантирован. Поля ключа лучше final: изменение их после put нарушает ожидаемый поиск в хеш-таблице.