Avatar ·

Как создать пустой массив в Kotlin? Примеры с intArrayOf, arrayOf и Array()

Привет, коллеги! Я недавно начал изучать Kotlin после Java и столкнулся с небольшой, но важной проблемой. Мне нужно создать пустой массив, чтобы потом динамически добавлять в него элементы (ну, или хотя бы инициализировать его заранее). В Java я привык делать так: ```java int[] arr = new int[0]; String[] arr2 = new String[0]; ``` Но в Kotlin я запутался. Пробовал писать: ```kotlin val arr = arrayOf() // Ошибка: Cannot infer type var list = intArrayOf() // Вроде работает, но тип? ``` Компилятор ругается, если я не указываю тип. А если я хочу массив строк или пользовательских объектов? Ещё читал про `Array(0) {...}`, но не понимаю, как это правильно использовать. Основная задача: создать пустой массив (например, для Int, String или своего класса), чтобы потом присвоить его переменной и, возможно, перезаписать новым массивом с данными. Без лишних костылей и с правильной типизацией. Буду благодарен за примеры с пояснениями! <<>>

1. Используйте специализированные функции для примитивных типов

Если вам нужен пустой массив для примитивных типов (Int, Long, Double, Boolean и т.д.), Kotlin предоставляет готовые функции:

val emptyInts: IntArray = intArrayOf()
val emptyLongs: LongArray = longArrayOf()
val emptyDoubles: DoubleArray = doubleArrayOf()
val emptyBooleans: BooleanArray = booleanArrayOf()
val emptyChars: CharArray = charArrayOf()

Эти функции сразу возвращают массивы нулевой длины. Тип указывать не обязательно — компилятор выводит его из имени функции.

2. Для массивов объектов (String, пользовательские классы) используйте arrayOf<T>()

Чтобы создать пустой массив объектов, нужно явно указать тип в угловых скобках:

val emptyStrings: Array<String> = arrayOf<String>()
val emptyUsers: Array<User> = arrayOf<User>()

Обратите внимание: без указания типа arrayOf() вызовет ошибку компиляции, так как Kotlin не может вывести тип из пустого списка аргументов.

3. Альтернатива — конструктор Array(size) { ... }

Можно использовать конструктор класса Array с лямбдой-инициализатором. Для пустого массива передаём размер 0:

val emptyStrings: Array<String> = Array(0) { "" } // лямбда не будет вызвана
val emptyUsers: Array<User> = Array(0) { User() }  // то же самое

Лямбда-инициализатор не выполняется для размера 0, поэтому можно передать любое значение — оно игнорируется. Однако этот способ менее читаемый, чем arrayOf<T>().

4. Как потом "добавить" элементы?

Массивы в Kotlin, как и в Java, имеют фиксированную длину. Вы не можете добавить элемент в пустой массив. Вместо этого нужно создать новый массив большего размера. Вот два подхода:

  • Использовать copyOf() — расширяет массив, заполняя новые элементы значениями по умолчанию (0 для Int, null для String и т.д.):
    var arr = intArrayOf()          // пустой массив
    arr = arr.copyOf(3)            // теперь [0, 0, 0]
    arr[0] = 42                    // [42, 0, 0]
    
  • Использовать plus() или оператор + — возвращает новый массив с добавленным элементом:
    var arr = arrayOf<String>()
    arr = arr + "Kotlin"           // ["Kotlin"]
    arr = arr + "Java"             // ["Kotlin", "Java"]
    

Но на практике для динамического добавления элементов лучше использовать списки (List, MutableList), так как они поддерживают изменяемый размер без копирования.

5. Рекомендация для начинающих

Если вы пишете код, где количество элементов заранее неизвестно, используйте mutableListOf():

val list = mutableListOf<Int>()
list.add(1)
list.add(2)
println(list) // [1, 2]

Массивы оставьте для случаев, когда размер фиксирован и известен заранее (например, для производительности или совместимости с Java API).

Итог: краткая шпаргалка

  • intArrayOf() — пустой массив Int
  • arrayOf<String>() — пустой массив String
  • Array(0) { ... } — общий конструктор
  • arrayOfNulls<String>(0) — если нужен пустой массив с nullable элементами

Главное — всегда указывайте тип при использовании arrayOf() для пустых массивов!

<<>>

Альтернативный подход: используйте arrayOfNulls() для nullable-массивов

Если вы хотите создать пустой массив, который потом будет заполняться объектами, которые могут быть null, удобно использовать функцию arrayOfNulls<T>(size). Для пустого массива передаём размер 0:

val emptyNullableStrings: Array<String?> = arrayOfNulls(0)
val emptyNullableUsers: Array<User?> = arrayOfNulls(0)

Этот подход явно создаёт массив с nullable-типом элемента. Если вы потом захотите расширить массив через copyOf(), новые элементы будут заполнены null, что удобно для последующей инициализации.

Ещё один лайфхак: для массивов примитивных типов можно использовать IntArray(0), BooleanArray(0) и т.д. — это эквивалентно вызовам intArrayOf(), но выглядит более явно:

val arr = IntArray(0) // пустой массив Int

Такой синтаксис может быть понятнее, если вы привыкли к конструкторам.