Ответ
При добавлении пары ключ-значение в Map (например, HashMap) с ключом, который уже присутствует в коллекции, старое значение, ассоциированное с этим ключом, перезаписывается новым значением. Ключ остается прежним. Это фундаментальное свойство Map — каждый ключ может быть связан только с одним значением.
Базовое поведение (перезапись):
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 10); // Добавляет пару ("Alice", 10)
scores.put("Alice", 25); // Перезаписывает значение. Теперь ("Alice", 25)
System.out.println(scores.get("Alice")); // Вывод: 25
System.out.println(scores.size()); // Вывод: 1 (ключ один)
Методы для "складывания" значений (если это требуется): Если по бизнес-логике нужно не перезаписать, а, например, сложить числовые значения, следует использовать специальные методы:
-
merge()— Идеален для агрегации:Map<String, Integer> totals = new HashMap<>(); totals.put("budget", 1000); // Если ключ "budget" существует, сложить старое и новое значение. // Если ключа нет, просто положить значение 500. totals.merge("budget", 500, Integer::sum); // Теперь "budget" = 1500 totals.merge("newItem", 300, Integer::sum); // Ключа не было -> "newItem" = 300 -
compute()— Полный контроль над вычислением нового значения:Map<String, List<String>> groups = new HashMap<>(); groups.compute("teamA", (key, currentList) -> { if (currentList == null) { currentList = new ArrayList<>(); } currentList.add("New Member"); return currentList; }); -
computeIfAbsent()/computeIfPresent()— Упрощенные версии для частых сценариев.
Важно: Стандартный put() всегда выполняет замену, а не сложение. Для агрегирующих операций необходимо явно использовать merge(), compute() или вручную получать старое значение.
Ответ 18+ 🔞
Ну, слушай, история про Map — это вообще классика, блядь. Представь себе, у тебя есть шкафчик, сука, с ключами. На каждом ключе написано имя, а внутри лежит хуйня какая-то. Ты пришёл, повесил свой ключ "Alice" и положил туда число 10. Всё, порядок.
А потом приходит какой-то мудак, тоже с ключом "Alice", и пытается запихнуть туда своё число 25. И что происходит, блядь? А происходит то, что старый пакет с десяткой выёбывается нахуй, а на его место ложится новая двадцатка с пятёркой. Ключ-то один и тот же, ёпта! Шкафчик не резиновый, чтобы для одного имени два отсека делать. Это фундаментально, как закон тяготения, блядь. Запомни раз и навсегда.
Вот, смотри, как это выглядит в коде, тут всё просто, как три копейки:
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 10); // Положил десятку для Алисы
scores.put("Alice", 25); // ААА, БЛЯДЬ! Выкинул десятку, положил двадцать пять!
System.out.println(scores.get("Alice")); // Вывод: 25 (десяточка, прости, сгинула)
System.out.println(scores.size()); // Вывод: 1 (ключ-то один, ёбаный насос!)
Вот и вся магия, сука. Старое значение накрылось медным тазом. Навсегда.
А если мне надо не заменить, а, например, ПРИБАВИТЬ, блядь? Ну, например, ты считаешь бабки, и тебе нужно не последнюю сумму хранить, а общую. Тут стандартный put() — это как топором по яйцам: отрубил и забыл. Не годится.
Для таких хитрожопых случаев есть специальные методы, которые не просто тупо заменяют, а думают, блядь.
-
merge()— царь и бог агрегации. Сказал "сложи" — он сложит. Сказал "сконкатенируй" — он сконкатенирует. Красота, ёпта!Map<String, Integer> totals = new HashMap<>(); totals.put("budget", 1000); // Бюджет был 1000 // Говорим: "Э, шкафчик, если для 'budget' что-то лежит, прибавь к этому 500. // А если нихуя не лежит, то просто положи 500 и не парься". totals.merge("budget", 500, Integer::sum); // Теперь "budget" = 1500, ебать! totals.merge("newItem", 300, Integer::sum); // Ключа не было -> просто кладём 300 -
compute()— полный контроль, как в кабине пилота. Хочешь — прибавляй, хочешь — список там формируй, хочешь — нахуй всё удаляй. Делаешь что хочешь.Map<String, List<String>> groups = new HashMap<>(); groups.compute("teamA", (key, currentList) -> { if (currentList == null) { // Если списка ещё нет, блядь... currentList = new ArrayList<>(); // ...создаём пустой! } currentList.add("New Member"); // Кидаем нового члена команды return currentList; // И возвращаем обновлённый список на место }); -
computeIfAbsent()/computeIfPresent()— это такие упрощённые братьяcompute(). Один работает, только если ключа НЕТ, а второй — только если ключ УЖЕ ЕСТЬ. Для ленивых, но умных.
Итог, блядь, запомни: Обычный put() — это тупой сапёр, который всегда подрывает старую мину. Если тебе надо не взорвать, а аккуратно разрядить и добавить своего тротила — используй merge() или compute(). Всё, вопрос закрыт, в рот меня чих-пых.