TGViewer
Библиотека Java разработчика Библиотека Java разработчика @bookjava · 10.1K subscribers
Post #4298 863
🧠 Как в Java сломать equals() и потерять данные в HashMap

Сегодня покажу, как неочевидный баг в equals()/hashCode() может привести к потере данных при работе с HashMap.

Допустим, у вас есть Entity:


public class User {
private String id;
private String name;

// equals/hashCode только по id
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}

@Override
public int hashCode() {
return Objects.hash(id);
}
}


Вроде норм. Но теперь добавим такого юзера в HashMap, а потом... изменим его id:


User user = new User();
user.setId("1");
user.setName("Alice");

Map<User, String> map = new HashMap<>();
map.put(user, "value");

user.setId("2"); // ⚠️ ключ стал "невидимым"

System.out.println(map.get(user)); // null 😱


📌 Почему так происходит?

HashMap ищет ключ по hashCode() → ищет бакет → сравнивает через equals(). А hashCode() уже другой, и объект "теряется".

💡 Совет: если вы используете объект как ключ в мапе или добавляете его в Set, не изменяйте его поля, участвующие в equals()/hashCode()!

📌 А как правильно?

- Делайте такие поля final;
- Или используйте неизменяемые типы (record);
- Или не используйте такие объекты как ключи вовсе.

Вот безопасный вариант с record:


public record User(String id, String name) {}


📲 Мы в MAX

👉@BookJava
  • 👍 6
  • 🥴 2
More from @bookjava
  1. Sep 27, 2026🧠 Ленивая инициализация через Supplier — элегантная альтернатива double-checked locking К…
  2. Sep 23, 2026Что такое механизм try-with-resources? Механизм try-with-resources в Java — это конструкци…
  3. Sep 21, 2026📌 picocli — это современная библиотека для создания CLI-приложений на Java. Она упрощает…
  4. Sep 18, 2026Double-brace инициализация в Java — это идиома, которая используется для инициализации кол…
  5. Sep 16, 2026🧠@Value vs @ConfigurationProperties — не выбирай наобум Оба способа хороши для конфигурац…
  6. Sep 14, 2026🧠 Трюк с @EventListener в Spring — убираем лишний @TransactionalEventListener Когда тебе…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →