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

Для чего нужен put() в HashMap?

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

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

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

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

# HashMap.put() метод: назначение и особенности

put() — это основной метод HashMap для добавления или обновления пар ключ-значение. Это самая частая операция при работе с HashMap.

Основное назначение

HashMap<String, Integer> ages = new HashMap<>();

// put() добавляет новую пару
ages.put("Alice", 25);
ages.put("Bob", 30);

// put() также ОБНОВЛЯЕТ существующий ключ
ages.put("Alice", 26); // Alice теперь 26, не 25

Сигнатура метода

V put(K key, V value)

Возвращает:

  • null если ключа не было
  • Предыдущее значение если ключ существовал
HashMap<String, Integer> map = new HashMap<>();

// Добавление нового ключа
Integer old = map.put("key1", 100);
System.out.println(old); // null (ключа не было)

// Обновление существующего ключа
old = map.put("key1", 200);
System.out.println(old); // 100 (предыдущее значение)

Важная особенность: возвращаемое значение

Используй возвращаемое значение для проверки, был ли ключ в наличии:

public class PutExample {
  
  public static void main(String[] args) {
    HashMap<String, String> users = new HashMap<>();
    
    String old = users.put("john", "john@example.com");
    if (old == null) {
      System.out.println("Новый пользователь добавлен");
    } else {
      System.out.println("Email пользователя обновлён: " + old);
    }
    
    old = users.put("john", "john.new@example.com");
    System.out.println("Предыдущий email: " + old); // john@example.com
  }
}

Различие put() vs putIfAbsent()

HashMap<String, Integer> map = new HashMap<>();

// put() ВСЕГДА обновляет
map.put("key", 1);
map.put("key", 2); // Перезаписано!
System.out.println(map.get("key")); // 2

// putIfAbsent() добавляет ТОЛЬКО если ключа нет
map.putIfAbsent("key", 3); // Не добавляет, key уже есть!
System.out.println(map.get("key")); // 2 (не изменилось)

// putIfAbsent() добавляет если ключа нет
map.putIfAbsent("newKey", 100);
System.out.println(map.get("newKey")); // 100

Внутренняя реализация put()

public V put(K key, V value) {
  // 1. Вычисли hash ключа
  int hash = hash(key);
  
  // 2. Найди индекс в массиве
  int index = hash & (capacity - 1);
  
  // 3. Проверь цепочку коллизий
  Node<K, V> node = table[index];
  while (node != null) {
    // 4. Если ключ найден — обнови значение и верни старое
    if (node.key.equals(key)) {
      V oldValue = node.value;
      node.value = value;
      return oldValue;
    }
    node = node.next;
  }
  
  // 5. Если ключа нет — добавь новый Node
  Node<K, V> newNode = new Node<>(hash, key, value);
  newNode.next = table[index];
  table[index] = newNode;
  size++;
  
  // 6. Проверь нужен ли resize
  if (size > threshold) {
    resize();
  }
  
  return null; // Ключа не было
}

Практические примеры

1. Счётчик с put()

HashMap<String, Integer> counter = new HashMap<>();

for (String word : words) {
  Integer count = counter.get(word);
  if (count == null) {
    counter.put(word, 1);
  } else {
    counter.put(word, count + 1);
  }
}

// Лучше: используй возвращаемое значение
for (String word : words) {
  Integer old = counter.put(word, counter.getOrDefault(word, 0) + 1);
}

2. Кэширование с put()

public class Cache {
  private HashMap<String, CachedValue> cache = new HashMap<>();
  
  public void cache(String key, Object value) {
    // put() добавляет или обновляет кэш
    cache.put(key, new CachedValue(value, System.currentTimeMillis()));
  }
  
  public Object get(String key) {
    CachedValue cached = cache.get(key);
    if (cached == null) return null;
    
    // Проверь TTL
    if (System.currentTimeMillis() - cached.timestamp > TTL) {
      cache.remove(key); // Удали устаревший кэш
      return null;
    }
    
    return cached.value;
  }
}

3. Конфигурация параметров

public class Config {
  private HashMap<String, String> params = new HashMap<>();
  
  public void setParameter(String name, String value) {
    String old = params.put(name, value);
    if (old != null) {
      log.info("Parameter {} updated from {} to {}", 
               name, old, value);
    } else {
      log.info("Parameter {} added with value {}", name, value);
    }
  }
}

4. putAll() для объединения HashMap'ов

HashMap<String, Integer> map1 = new HashMap<>();
map1.put("a", 1);
map1.put("b", 2);

HashMap<String, Integer> map2 = new HashMap<>();
map2.put("b", 20);  // Перезапишет значение из map1
map2.put("c", 3);

map1.putAll(map2);
System.out.println(map1);
// {a=1, b=20, c=3}

Сложность операции

ОперацияСложностьКомментарий
put() в среднемO(1)Прямой доступ по хешу
put() в худшемO(n)Если все ключи коллизируют
Resize в put()O(n)Пересчет всех хешей

Потокобезопасность

HashMap НЕ потокобезопасен. При многопоточном доступе используй:

// Вариант 1: Collections.synchronizedMap()
Map<String, Integer> syncMap = 
  Collections.synchronizedMap(new HashMap<>());

// Вариант 2: ConcurrentHashMap
ConcurrentHashMap<String, Integer> concurrent = 
  new ConcurrentHashMap<>();

// ConcurrentHashMap более эффективен для многопоточности
concurrent.put("key", 1);

Null значения в put()

HashMap позволяет null ключи и null значения:

HashMap<String, String> map = new HashMap<>();

map.put(null, "null key");      // Разрешено
map.put("null value", null);    // Разрешено
map.put(null, null);            // Разрешено

System.out.println(map.get(null)); // null key

Но это может привести к ошибкам, поэтому избегай null в production коде.

Лучшие практики

  1. Используй putIfAbsent() если не нужна перезапись
map.putIfAbsent("key", 100); // Безопаснее
  1. Используй getOrDefault() с put()
map.put("key", map.getOrDefault("key", 0) + 1);
  1. Проверяй возвращаемое значение
String old = map.put("key", "newValue");
if (old != null) {
  log.info("Updated existing value");
}
  1. Используй ConcurrentHashMap в многопоточности
ConcurrentHashMap<K, V> map = new ConcurrentHashMap<>();
map.put(key, value);

Итог

put() — это основная операция HashMap для добавления и обновления элементов. Ключевые моменты:
  1. put() возвращает предыдущее значение (или null)
  2. Сложность в среднем O(1), в худшем O(n)
  3. Используй putIfAbsent() для безопасности
  4. HashMap не потокобезопасен — используй ConcurrentHashMap