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

Как вставить два разных объекта по одному ключу в HashMap

1.3 Junior🔥 151 комментариев
#Коллекции

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

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

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

# Вставка двух объектов по одному ключу в HashMap

Проблема и суть вопроса

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

HashMap<String, String> map = new HashMap<>();
map.put("key", "value1");
map.put("key", "value2");
System.out.println(map.get("key")); // value2 - value1 потеряно!

Это является базовым поведением HashMap. Однако есть несколько способов хранить несколько значений по одному ключу.

Решение 1: HashMap с коллекциями значений

Самое частое решение — использовать коллекцию (List, Set) в качестве значения:

// HashMap с List значений
HashMap<String, List<String>> multiMap = new HashMap<>();

// Вставка первого значения
multiMap.put("key", new ArrayList<>());
multiMap.get("key").add("value1");

// Вставка второго значения по тому же ключу
multiMap.get("key").add("value2");

System.out.println(multiMap.get("key")); // [value1, value2]

Более удобный способ с помощью computeIfAbsent:

public class MultiValueMap {
    private final HashMap<String, List<String>> map = new HashMap<>();
    
    public void put(String key, String value) {
        map.computeIfAbsent(key, k -> new ArrayList<>())
           .add(value);
    }
    
    public List<String> get(String key) {
        return map.getOrDefault(key, Collections.emptyList());
    }
    
    public static void main(String[] args) {
        MultiValueMap mm = new MultiValueMap();
        mm.put("key", "value1");
        mm.put("key", "value2");
        System.out.println(mm.get("key")); // [value1, value2]
    }
}

Решение 2: HashMap с HashSet

Если нужна уникальность значений, используем Set:

HashMap<String, Set<String>> multiMap = new HashMap<>();

multiMap.computeIfAbsent("key", k -> new HashSet<>())
        .add("value1");
multiMap.computeIfAbsent("key", k -> new HashSet<>())
        .add("value2");

System.out.println(multiMap.get("key")); // [value1, value2]

Решение 3: Использование Apache Commons MultiMap

Для удобства можно использовать готовую реализацию из Apache Commons Collections:

import org.apache.commons.collections4.MultiMap;
import org.apache.commons.collections4.map.MultiValueMap;

public class ApacheMultiMapExample {
    public static void main(String[] args) {
        MultiMap<String, String> multiMap = new MultiValueMap<>();
        
        multiMap.put("key", "value1");
        multiMap.put("key", "value2");
        
        System.out.println(multiMap.get("key")); // [value1, value2]
    }
}

Решение 4: Google Guava Multimap

Guava предоставляет несколько вариантов MultiMap:

import com.google.common.collect.Multimap;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashMultimap;

public class GuavaMultimapExample {
    public static void main(String[] args) {
        // ListMultimap - позволяет дубликаты
        Multimap<String, String> listMultimap = ArrayListMultimap.create();
        listMultimap.put("key", "value1");
        listMultimap.put("key", "value2");
        listMultimap.put("key", "value1"); // Дубликат допускается
        
        System.out.println(listMultimap.get("key")); 
        // [value1, value2, value1]
        
        // SetMultimap - уникальные значения
        Multimap<String, String> setMultimap = HashMultimap.create();
        setMultimap.put("key", "value1");
        setMultimap.put("key", "value2");
        setMultimap.put("key", "value1"); // Дубликат игнорируется
        
        System.out.println(setMultimap.get("key"));
        // [value1, value2]
    }
}

Сравнение подходов

ПодходВес кодаПроизводительностьФлексибильность
HashMap<K, List<V>>СреднийОтличнаяВысокая
HashMap<K, Set<V>>СреднийОтличнаяВысокая
Apache CommonsМалыйХорошаяСредняя
Google GuavaМалыйХорошаяВысокая

Практический пример: Логирование событий по ключу

public class EventLog {
    private final Map<String, List<String>> events = new HashMap<>();
    
    public void logEvent(String category, String event) {
        events.computeIfAbsent(category, k -> new ArrayList<>())
              .add(event);
    }
    
    public List<String> getEvents(String category) {
        return events.getOrDefault(category, Collections.emptyList());
    }
    
    public static void main(String[] args) {
        EventLog log = new EventLog();
        log.logEvent("auth", "User login at 10:00");
        log.logEvent("auth", "User logout at 11:00");
        log.logEvent("purchase", "Item A bought");
        log.logEvent("purchase", "Item B bought");
        
        System.out.println(log.getEvents("auth"));
        // [User login at 10:00, User logout at 11:00]
    }
}

Важные моменты

1. Потокобезопасность — если используете в многопоточной среде:

Map<String, List<String>> syncMap = 
    Collections.synchronizedMap(new HashMap<>());

2. Производительность — если часто добавляете значения, используйте LinkedList вместо ArrayList на чтение происходит дольше, но insertion быстрее в начале/конце.

3. Памяти — храня коллекции в HashMap, помните о потреблении памяти.

Итого

Для вставки двух разных объектов по одному ключу:

  • Стандартное решение: HashMap<K, List<V>> с computeIfAbsent()
  • Для уникальности: HashMap<K, Set<V>>
  • Готовое решение: Google Guava Multimap или Apache Commons MultiMap

Выбор зависит от требований и предпочтений команды. На интервью хорошо будет показать несколько вариантов и объяснить плюсы/минусы каждого.

Как вставить два разных объекта по одному ключу в HashMap | PrepBro