Вступ:
HashMap (Хеш-мапи) є основою багатьох Java-додатків, але вони не завжди працюють без помилок. Невірне використання методів equals
та hashCode
може призвести до несподіваних багів. Давайте перевіримо, чи зможете ви знайти проблему в цьому сценарії.
Питання:
Розглянемо цей код:
import java.util.HashMap;
import java.util.Objects;
class Key {
private String id;
public Key(String id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Key key = (Key) o;
return Objects.equals(id, key.id);
}
}
public class HashMapDemo {
public static void main(String[] args) {
HashMap map = new HashMap<>();
map.put(new Key("1"), "Value1");
System.out.println(map.get(new Key("1")));
}
}
Що виведе ця програма?
- Чи виведе вона “Value1”?
- Якщо ні, то чому?
- Як це виправити?
Відповідь:
- Чи виведе вона “Value1”? Ні, вона виведе
null
. - Чому? Хоча метод
equals
правильно перевизначено, методhashCode
не реалізований. У HashMap (Хеш-мапі) ключі зберігаються в кошиках на основі їх хеш-кодів. Без належної реалізації методуhashCode
новий об'єктKey("1")
не потрапляє в той самий кошик, що і оригінальний ключ. - Як це виправити? Додайте правильну реалізацію методу
hashCode
:
@Override public int hashCode() {
return Objects.hash(id);
}
З цією поправкою програма правильно виведе “Value1”.
Практичні висновки:
- Завжди перевизначайте
equals
таhashCode
разом: Вони повинні працювати разом, щоб забезпечити правильну поведінку в колекціях, таких як HashMap (Хеш-мапа). - Використовуйте
Objects.hash
: Це спрощує генерування хеш-кодів. - Тестуйте з реальними випадками: Завжди тестуйте свої користувацькі об'єкти в колекціях, щоб забезпечити правильну поведінку.
Будьте допитливими і щасливого кодування! 🚀
Перекладено з: Day 3 of the Java & Spring Interview Series — Why Isn’t My HashMap Key Being Found?