Что выведет в консоль код на Kotlin где создаётся mutableMap затем к нему применяется plus и apply но без изменения исходной коллекции
Комментарии (3)
Ответ сгенерирован нейросетью и может содержать ошибки
Отличный вопрос! Он проверяет понимание нюансов работы с коллекциями Kotlin, особенно с операторами plus и областью видимости apply. Вот подробный разбор.
Краткий ответ
Код выведет в консоль неизменённое исходное содержимое MutableMap, так как оператор plus в Kotlin для коллекций является не-мутабельным (immutable): он возвращает новую коллекцию, не изменяя оригинал. Даже внутри блока apply, который возвращает получателя (this), сама операция plus создаёт новую карту, но не присваивает её обратно исходной переменной.
Подробное объяснение с примером
Рассмотрим типичный код, который может быть на собеседовании:
fun main() {
val mutableMap = mutableMapOf("A" to 1, "B" to 2)
val result = mutableMap.apply {
plus("C" to 3) // Ключевой момент!
put("D", 4) // Для контраста
}
println("Исходная mutableMap: $mutableMap")
println("Результат apply: $result")
}
Вывод в консоль будет:
Исходная mutableMap: {A=1, B=2, D=4}
Результат apply: {A=1, B=2, D=4}
Почему так происходит? Пошаговый анализ:
-
Создание
mutableMap: Мы создаём изменяемую карту{"A"=1, "B"=2}. Ключевое словоvalзащищает только ссылку на объект от изменения, но не сам объект. -
Работа блока
apply:
* Внутри `apply` контекстом (`this`) становится сама `mutableMap`.
* **Строка `plus("C" to 3)`**: Это вызов оператора `plus`. Для `Map` (и большинства коллекций Kotlin по умолчанию) этот оператор **не модифицирует** исходную коллекцию. Он **возвращает новую карту** `{"A"=1, "B"=2, "C"=3}`. Однако этот результат **никому не присваивается** и просто игнорируется. Исходная `mutableMap` остаётся без изменений на этом шаге.
* **Строка `put("D", 4)`**: Метод `put` является **мутабельной** операцией. Он напрямую изменяет состояние получателя, то есть исходной `mutableMap`. Теперь она содержит `{"A"=1, "B"=2, "D"=4}`.
- Результат: Блок
applyвозвращает получателя — ссылку на изменённую (благодаряput)mutableMap. Иresult, иmutableMapссылаются на один и тот же объект в памяти.
Важные концепции Kotlin, которые иллюстрирует этот пример:
-
plusvs мутабельные операции (put,add): Стандартные операторыplus(+) иminus(-) для коллекций не изменяют оригинал. Они следуют принципам иммутабельности. Для изменений "на месте" используются специальные методы:put,add,removeи т.д. -
Разница между
mutableMap.plus()иmutableMap +=: Это частая причина ошибок.mutableMap.plus("C" to 3) // Возвращает новую карту, оригинал не меняется. mutableMap += ("C" to 3) // Эквивалентно: mutableMap = mutableMap.plus(...)
Оператор `+=` для `var`-переменной перезапишет ссылку на новую карту. Для `val` это вызовет ошибку компиляции.
- Область видимости
apply:applyпредоставляет доступ кthis(получателю) и всегда возвращает этотthis. Он не магическим образом перехватывает результаты всех операций внутри.
Как получить ожидаемое поведение (добавить элемент и вывести новую карту)?
Если цель — создать новую карту на основе старой, нужно явно присвоить результат операции plus:
val newMap = mutableMap + ("C" to 3) // Предпочтительный способ (операторная форма)
// или
val newMap2 = mutableMap.plus("C" to 3)
// или внутри apply, но с присваиванием (менее читаемо):
val newMap3 = mutableMap.apply { this + ("C" to 3) } // Всё равно не сработает, apply вернёт старую map!
// Правильно так:
val newMap4 = mutableMap.toMutableMap().apply { put("C", 3) } // Создаём копию, затем меняем её
Вывод для собеседования
На собеседовании следует ответить так: "Код выведет исходную карту без добавленного через plus элемента, потому что plus для коллекций Kotlin — это операция, возвращающая новый объект, а не изменяющая существующий. Блок apply возвращает получателя (this), которым является исходная mutableMap. Если внутри apply не вызван мутабельный метод (put), то состояние получателя не изменится. Этот вопрос проверяет понимание различия между мутабельными и иммутабельными операциями в Kotlin и знание того, что стандартные операторы plus/minus работают в функциональном стиле."