Комментарии (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 коде.
Лучшие практики
- Используй putIfAbsent() если не нужна перезапись
map.putIfAbsent("key", 100); // Безопаснее
- Используй getOrDefault() с put()
map.put("key", map.getOrDefault("key", 0) + 1);
- Проверяй возвращаемое значение
String old = map.put("key", "newValue");
if (old != null) {
log.info("Updated existing value");
}
- Используй ConcurrentHashMap в многопоточности
ConcurrentHashMap<K, V> map = new ConcurrentHashMap<>();
map.put(key, value);
Итог
put() — это основная операция HashMap для добавления и обновления элементов. Ключевые моменты:
- put() возвращает предыдущее значение (или null)
- Сложность в среднем O(1), в худшем O(n)
- Используй putIfAbsent() для безопасности
- HashMap не потокобезопасен — используй ConcurrentHashMap