Avatar ·

Как инициализировать массив в Kotlin с конкретными значениями?

Привет! Я только начал изучать Kotlin после Java и столкнулся с проблемой инициализации массивов.

В Java я привык делать так: int[] numbers = {1, 2, 3, 4, 5}; или String[] names = {"Alice", "Bob"};. Всё просто и понятно.

Но в Kotlin я вижу несколько разных способов и запутался. Пробовал написать:

val numbers = {1, 2, 3} // Ошибка компиляции

Потом прочитал, что нужно использовать arrayOf():

val numbers = arrayOf(1, 2, 3)

Это работает, но я не понимаю: это правильный способ? А что делать, если я хочу массив из null? Или если мне нужен массив примитивных типов (IntArray, BooleanArray)?

Ещё я видел такой код:

val numbers = IntArray(5) { it * 2 } // Что это значит?

Или такой:

val arr = Array(3) { "" }

Я совсем запутался. Подскажите, пожалуйста:

  • Как правильно инициализировать массив с явными значениями?
  • В чём разница между arrayOf, IntArray и Array(size) {}?
  • Как создать массив с null-элементами?

Желательно с примерами кода. Заранее спасибо!

<<>>

Основные способы инициализации массивов в Kotlin

В Kotlin нет синтаксиса {1, 2, 3} как в Java, но есть несколько удобных альтернатив. Давайте разберём все варианты.

1. Самый простой способ: arrayOf()

Это аналог Java-инициализации через фигурные скобки. Просто перечисляете значения через запятую:

val numbers = arrayOf(1, 2, 3, 4, 5)
val names = arrayOf("Alice", "Bob", "Charlie")
val mix = arrayOf(1, "hello", 3.14) // Массив Any? — работает, но не рекомендуется

Тип массива выводится автоматически. В первом случае это Array<Int>, во втором — Array<String>.

2. Массивы примитивных типов (IntArray, BooleanArray, FloatArray и т.д.)

Если вам нужен массив без автоупаковки (как int[] в Java), используйте специальные классы:

val intArray = intArrayOf(1, 2, 3)      // IntArray (примитивный int[])
val boolArray = booleanArrayOf(true, false, true) // BooleanArray
val floatArray = floatArrayOf(1.5f, 2.7f) // FloatArray
val charArray = charArrayOf('a', 'b')    // CharArray

Разница с arrayOf(1, 2, 3) в производительности: IntArray хранит значения как примитивные int, а Array<Int> — как объекты Integer.

3. Создание массива через конструктор с лямбдой

Это мощный способ, когда размер известен, а значения вычисляются:

// Массив из 5 элементов: [0, 2, 4, 6, 8]
val squares = IntArray(5) { index -> index * 2 }

// Массив строк: ["A0", "A1", "A2"]
val labels = Array(3) { i -> "A$i" }

// Массив из null (для nullable типов)
val nullableArray = arrayOfNulls<String>(3) // [null, null, null]

Здесь it — это индекс элемента (от 0 до size-1). Лямбда вызывается для каждого индекса.

4. Массивы с null-элементами

Если вам нужен массив, который может содержать null, используйте:

// Способ 1: arrayOfNulls (все элементы null)
val nullable1 = arrayOfNulls<String>(3)

// Способ 2: arrayOf с явным указанием типа
val nullable2: Array<String?> = arrayOf(null, "hello", null)

// Способ 3: конструктор с лямбдой
val nullable3 = Array<String?>(3) { null } // все null
val nullable4 = Array<Int?>(5) { if (it % 2 == 0) it else null } // [0, null, 2, null, 4]

5. Инициализация из коллекции

Если у вас есть список или другой Iterable:

val list = listOf(1, 2, 3)
val arrayFromList = list.toTypedArray() // Array<Int>

val mutableList = mutableListOf("a", "b")
val arrayFromMutable = mutableList.toTypedArray() // Array<String>

Краткая шпаргалка

  • arrayOf(1, 2, 3) — универсальный способ для любых типов (но возможна автоупаковка).
  • intArrayOf(1, 2, 3) — для примитивов (Int, Boolean, Float и т.д.) без автоупаковки.
  • Array(size) { lambda } — когда значения вычисляются по индексу.
  • arrayOfNulls<T>(size) — массив, заполненный null (только для nullable типов).
  • list.toTypedArray() — из коллекции в массив.

Пример полного использования

fun main() {
    // 1. Явные значения
    val fruits = arrayOf("Apple", "Banana", "Cherry")
    
    // 2. Примитивный массив
    val primes = intArrayOf(2, 3, 5, 7, 11)
    
    // 3. Динамическое заполнение
    val evenNumbers = IntArray(10) { it * 2 } // [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    
    // 4. С null
    val maybeNumbers: Array<Int?> = arrayOf(1, null, 3, null)
    
    // 5. Из списка
    val list = listOf("Kotlin", "Java")
    val array = list.toTypedArray()
    
    // Печать
    println(fruits.contentToString())   // [Apple, Banana, Cherry]
    println(primes.contentToString())   // [2, 3, 5, 7, 11]
    println(evenNumbers.contentToString())
    println(maybeNumbers.contentToString())
}

Выберите способ под вашу задачу. Для простых случаев arrayOf() — идеальный вариант. Для производительности — intArrayOf() и аналоги. Для динамического заполнения — конструктор с лямбдой.

<<>>

Альтернативный подход: использование Array с конструктором и fill()

Иногда нужно создать массив фиксированного размера, а потом заполнить его значениями. В Kotlin для этого есть метод fill():

val arr = Array<Int>(5) { 0 } // [0, 0, 0, 0, 0]
arr.fill(42) // Теперь все элементы = 42

Или можно сначала создать пустой массив (с дефолтными значениями), а потом перезаписать:

val numbers = IntArray(3) // [0, 0, 0] для IntArray
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30

Массивы с многомерными данными

Для двумерных массивов используйте вложенные вызовы:

val matrix = Array(3) { row ->
    IntArray(3) { col -> row * 3 + col + 1 }
}
// [
//   [1, 2, 3],
//   [4, 5, 6],
//   [7, 8, 9]
// ]

Важное замечание про неизменяемость

В Kotlin массивы мутабельны по содержимому, но неизменяемы по размеру. Если нужен динамический список — используйте MutableList:

val dynamicList = mutableListOf(1, 2, 3)
dynamicList.add(4) // Работает
// Для массива add() нет!

Это часто путает новичков. Помните: массив — это фиксированный набор элементов, а список — динамическая коллекция.