Sobes.tech
Назад к вопросам
Senior
6

public static void main(String args[]) { checkMap(new HashMap<>()); checkMap(new LinkedHashMap<>()); checkMap(new TreeMap<>()); } private static void checkMap(Map<Person, String> map) { System.out.println("Checking " + map.getClass()); Person ivan = new Person("Иван"); Person peter = new Person("Пётр"); Person maria1 = new Person("Мария"); Person maria2 = new Person("Мария"); map.put(ivan, ivan.name); map.put(peter, peter.name); map.put(maria1, maria1.name); map.put(maria2, maria2.name); // iterate and println for (Map.Entry<Person, String> entry : map.entrySet()) { System.out.println(entry); } // maria1.setName("Анна-Мария"); // maria2.setName("Анна-Мария"); System.out.println(map.get(maria1)); System.out.println(map.get(maria2)); System.out.println("==================================="); }

Компании, где спрашивали
IT OneIT One

Ответ от нейросети

sobes.tech AI

В данном коде создаются три разных типа Map: HashMap, LinkedHashMap и TreeMap, и в каждую кладутся объекты Person с одинаковыми именами.

Ключевой момент — как Map определяет уникальность ключей:

  • HashMap и LinkedHashMap используют методы hashCode() и equals() для сравнения ключей.
  • TreeMap использует compareTo() (или Comparator) для сортировки и сравнения ключей.

Если класс Person не переопределяет equals() и hashCode(), то для HashMap и LinkedHashMap разные объекты с одинаковыми именами будут считаться разными ключами, и в Map будут храниться оба.

TreeMap, если Person не реализует Comparable или не передан Comparator, вызовет ошибку.

Пример:

class Person {
    String name;
    Person(String name) { this.name = name; }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person p = (Person) o;
        return name.equals(p.name);
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }
}

Если использовать такой класс, то HashMap и LinkedHashMap будут считать maria1 и maria2 одинаковыми ключами, и значение для второго вставленного перезапишет первое.

TreeMap требует, чтобы Person реализовал Comparable:

class Person implements Comparable<Person> {
    String name;
    // конструктор
    @Override
    public int compareTo(Person other) {
        return this.name.compareTo(other.name);
    }
    // equals и hashCode тоже желательно переопределить
}

Таким образом, поведение Map зависит от реализации методов сравнения ключей. Если после изменения имени объекта (раскомментировать строки с setName) — ключи в Map могут перестать корректно находиться, так как изменился хэш или порядок сравнения, что нарушает контракт Map.

Вывод: для корректной работы Map ключи должны быть неизменяемыми или не менять поля, участвующие в equals/hashCode/compareTo после помещения в Map.