Как инициализировать список (List<T>) в Kotlin? Разбираем все способы
Основные способы инициализации списков в Kotlin
В Kotlin есть чёткое разделение на неизменяемые (read-only) и изменяемые (mutable) списки. Это сделано для безопасности — по умолчанию список не предполагает изменения, что предотвращает случайные ошибки.
1. Неизменяемые списки (List)
Используйте функцию listOf(). Такой список нельзя изменить после создания: нет методов add, remove и т.д.
val numbers: List<Int> = listOf(1, 2, 3, 4, 5)
val emptyList: List<String> = listOf() // пустой список
val singleList: List<String> = listOf("Kotlin") // список из одного элемента
Обратите внимание: тип List<T> — это интерфейс, а listOf() возвращает оптимизированную реализацию (обычно java.util.Arrays.ArrayList или java.util.Collections.emptyList()).
2. Изменяемые списки (MutableList)
Для списков, которые вы планируете изменять, используйте mutableListOf():
val mutableNumbers = mutableListOf(1, 2, 3)
mutableNumbers.add(4) // [1, 2, 3, 4]
mutableNumbers.remove(2) // [1, 3, 4]
mutableNumbers[0] = 10 // [10, 3, 4]
// Пустой изменяемый список
val emptyMutable = mutableListOf<String>()
По умолчанию mutableListOf() создаёт ArrayList. Вы также можете явно указать реализацию:
val arrayList = ArrayList<String>() // эквивалентно mutableListOf()
val linkedList = LinkedList<String>()
3. Инициализация с помощью конструкторов
Вы можете использовать конкретные классы коллекций Java, но Kotlin рекомендует свои функции-фабрики. Однако если вам нужен список фиксированного размера с одним значением:
// Список из 10 нулей
val zeros = MutableList(10) { 0 } // [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
// Список с индексами в качестве значений
val indices = MutableList(5) { index -> index * index } // [0, 1, 4, 9, 16]
Конструктор MutableList(size, init) — очень мощный инструмент, позволяющий заполнить список любыми значениями через лямбду.
4. Преобразование из других коллекций
Часто список получается из другого источника (например, из массива или Set):
val array = intArrayOf(1, 2, 3)
val listFromArray: List<Int> = array.toList()
val set = setOf("a", "b")
val mutableFromSet: MutableList<String> = set.toMutableList()
5. Инициализация с помощью билдера (для сложной логики)
Если нужно добавить элементы по условию, используйте buildList (доступен с Kotlin 1.3):
val complexList = buildList {
add("start")
if (someCondition) {
add("condition met")
}
addAll(listOf("end1", "end2"))
}
// Результат: неизменяемый список
Важные моменты
- Не путайте
ListиMutableList. Если вы объявилиval list: List<Int> = ..., то не сможете изменить его, даже если внутри он mutable. Это защита на уровне интерфейса. - Используйте
listOf()по умолчанию. Если не планируете изменять список, всегда выбирайте неизменяемую версию — это делает код безопаснее и читаемее. - Производительность.
listOf()для малых списков (до 2 элементов) может возвращать специальные оптимизированные классы. Для больших —ArrayList.
Пример для новичка
fun main() {
// Неизменяемый список дней недели
val daysOfWeek = listOf("Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс")
// Изменяемый список для задач
val tasks = mutableListOf("Купить продукты", "Помыть посуду")
tasks.add("Покормить кота")
tasks.removeAt(0)
println(daysOfWeek)
println(tasks)
}
Теперь вы знаете все основные способы. Начните с listOf и mutableListOf, а когда освоитесь — используйте MutableList(size) { ... } для эффективного заполнения.
Альтернативный подход: использование Java-совместимости
Если вы пришли из Java и хотите использовать привычный синтаксис, Kotlin позволяет напрямую работать с Java-коллекциями:
import java.util.ArrayList
val list = ArrayList<String>()
list.add("Hello")
list.add("World")
Но помните: ArrayList в Kotlin — это тот же java.util.ArrayList, и он всегда изменяемый. Однако такой код менее "идиоматичен" для Kotlin. Лучше использовать mutableListOf() — он короче и понятнее.
Ещё один способ: инициализация через spread-оператор
Если у вас есть массив, вы можете "развернуть" его в список:
val array = arrayOf("A", "B", "C")
val list = listOf(*array) // spread-оператор *
println(list) // [A, B, C]
Это удобно, когда нужно быстро преобразовать массив в неизменяемый список без вызова toList().
Для пуристов: использование конструктора с vararg
val list = listOf("one", "two", "three") // vararg в действии
Функция listOf принимает vararg elements: T, поэтому вы можете передавать любое количество элементов. Это самый простой и читаемый способ для небольших списков.
В итоге: для 90% случаев вам хватит listOf() и mutableListOf(). Остальные способы — для специфических ситуаций.