← Назад к вопросам

Могут ли два одинаковых элемента лежать в HashMap

2.2 Middle🔥 241 комментариев
#Коллекции

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Могут ли два одинаковых элемента лежать в HashMap?

Ответ зависит от того, что мы понимаем под «одинаковыми элементами». В HashMap не могут быть два одинаковых ключа, но могут быть два одинаковых значения.

Два одинаковых значения — ДА

В HashMap совершенно нормально иметь несколько одинаковых значений (values), связанные с разными ключами.

HashMap<String, String> map = new HashMap<>();
map.put("key1", "value");
map.put("key2", "value");  // Одинаковое значение
map.put("key3", "value");  // Ещё одно такое же значение

System.out.println(map.values()); // [value, value, value]
// Это совершенно нормально

Почему это возможно? Потому что HashMap гарантирует уникальность только ключей, а не значений. Разные ключи могут указывать на одно и то же значение.

HashMap<Integer, String> cityMap = new HashMap<>();
cityMap.put(1, "New York");
cityMap.put(2, "Paris");
cityMap.put(3, "New York");  // Повторяющееся значение

System.out.println(cityMap); // {1=New York, 2=Paris, 3=New York}
System.out.println(cityMap.values()); // [New York, Paris, New York]

Два одинаковых ключа — НЕТ

В HashMap не может быть двух одинаковых ключей. Если вы попытаетесь добавить ключ, который уже существует, произойдёт перезапись значения, а не добавление нового элемента.

HashMap<String, Integer> scores = new HashMap<>();
scores.put("Alice", 100);
scores.put("Bob", 85);
scores.put("Alice", 95);  // Попытка добавить существующий ключ

System.out.println(scores);     // {Bob=85, Alice=95}
System.out.println(scores.size()); // 2, не 3!

Второе значение для ключа "Alice" заменило первое значение (100 → 95), так что размер HashMap остался 2.

Как HashMap обеспечивает уникальность ключей?

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

1. hashCode()

Вычисляет хеш-функцию, определяющую, в какой бакет (bucket) поместить ключ.

String key1 = "Alice";
String key2 = "Alice";
String key3 = "Bob";

System.out.println(key1.hashCode()); // 2093164
System.out.println(key2.hashCode()); // 2093164 (ОДИНАКОВЫЙ!)
System.out.println(key3.hashCode());  // 66134 (ДРУГОЙ)

2. equals()

Дополнительная проверка, чтобы убедиться, что ключи действительно одинаковые.

HashMap<String, Integer> map = new HashMap<>();
map.put("key", 1);
map.put("key", 2);

String existing = "key";
String newKey = new String("key");

System.out.println(existing.equals(newKey));    // true
System.out.println(existing == newKey);         // false (разные объекты)
System.out.println(existing.hashCode() == newKey.hashCode()); // true

// HashMap считает это одним ключом
map.put(newKey, 3);
System.out.println(map); // {key=3}
System.out.println(map.size()); // 1

Процесс добавления в HashMap

map.put("Alice", 100);
  1. Вычисляется hash = "Alice".hashCode()
  2. HashMap находит бакет по индексу: bucketIndex = hash & (capacity - 1)
  3. В бакете проверяются существующие ключи:
    • Если ключа нет → добавляется новая пара
    • Если ключ найден через equals() → значение перезаписывается
    • Если hashCode одинаков, но equals вернул false → collision (коллизия)
HashMap<String, Integer> map = new HashMap<>();

// Добавление первого ключа
map.put("A", 1);
// hashCode("A") → hash1, поместить в bucket[hash1]

// Добавление другого ключа
map.put("B", 2);
// hashCode("B") → hash2 (отличается), поместить в bucket[hash2]

// Добавление существующего ключа
map.put("A", 10);
// hashCode("A") → hash1 (тот же), найти в bucket[hash1]
// equals("A", "A") → true, перезаписать значение
// Результат: {A=10, B=2}

Практический пример с собственным классом

public class Person {
    public String name;
    public int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return name.equals(person.name) && age == person.age;
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

// Использование в HashMap
HashMap<Person, String> map = new HashMap<>();

Person p1 = new Person("Alice", 30);
Person p2 = new Person("Alice", 30);
Person p3 = new Person("Bob", 25);

map.put(p1, "Developer");
map.put(p2, "Engineer");  // p2.equals(p1) = true, перезапишет
map.put(p3, "Manager");

System.out.println(map.size()); // 2, не 3!
System.out.println(map); // {Person{Alice,30}=Engineer, Person{Bob,25}=Manager}

Заметьте: несмотря на то, что p1 и p2 — это разные объекты в памяти, HashMap считает их одним ключом, потому что p1.equals(p2) вернул true.

Если не переопределить equals() и hashCode()

Если вы используете объект как ключ, но не переопределили equals() и hashCode(), получится неожиданное поведение:

public class BadPerson {
    public String name;
    public int age;
    
    public BadPerson(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // equals() и hashCode() НЕ переопределены
}

// Проблема
HashMap<BadPerson, String> map = new HashMap<>();
BadPerson p1 = new BadPerson("Alice", 30);
BadPerson p2 = new BadPerson("Alice", 30);

map.put(p1, "Developer");
map.put(p2, "Engineer");

System.out.println(map.size()); // 2 (неправильно!)
// Потому что p1.equals(p2) использует Object.equals(),
// который проверяет только идентичность (==)

Итоговая таблица

ВопросОтветПочему
Могут ли два одинаковых значения?ДАHashMap гарантирует уникальность только ключей
Могут ли два одинаковых ключа?НЕТHashMap проверяет через equals() и hashCode()
Что случится с дублирующимся ключом?ПерезаписьЗначение старого ключа заменяется новым
Как HashMap узнаёт, одинаковые ли ключи?hashCode() + equals()Сначала проверяет хеш, потом точное равенство

Вывод

ДА, два одинаковых элемента могут лежать в HashMap — если это значения (не ключи). HashMap гарантирует уникальность только ключей, используя hashCode() и equals() для их идентификации. Если вы попытаетесь добавить существующий ключ, произойдёт перезапись значения, а не добавление нового элемента.

Могут ли два одинаковых элемента лежать в HashMap | PrepBro