Avatar ·

Как объявить массив строк в Kotlin? Эквивалент Java String[]

Я только начал изучать Kotlin после Java, и столкнулся с простой, но сбивающей с толку проблемой. В Java я привык писать: ```java String[] names = new String[]{"Alice", "Bob", "Charlie"}; ``` Но в Kotlin я вижу несколько вариантов, и не понимаю, какой из них правильный. Я пробовал: ```kotlin val names = arrayOf("Alice", "Bob", "Charlie") ``` Но это возвращает `Array`, а не `String[]`. Есть ли разница? Или мне нужно использовать `Array` везде? Также я наткнулся на `listOf("Alice", "Bob", "Charlie")`, который возвращает `List`. Но мне нужен именно массив, потому что я передаю его в Java-метод, который ожидает `String[]`. Подскажите, пожалуйста, какой синтаксис в Kotlin соответствует Java `String[]`? И как правильно создать массив строк, если я знаю размер, но не знаю значения заранее? В Java я бы написал `String[] names = new String[10];`, а в Kotlin? Буду благодарен за примеры с кодом. <<>>

Прямой аналог: Array<String> и фабричные функции

В Kotlin нет синтаксического сахара вроде String[], но есть полноценная замена — Array<String>. Это и есть эквивалент Java-массива строк. Разница только в синтаксисе: Kotlin использует дженерики вместо квадратных скобок.

1. Создание массива с известными элементами

Используйте функцию arrayOf():

// Kotlin
val names: Array<String> = arrayOf("Alice", "Bob", "Charlie")
// Тип можно не указывать — компилятор выведет его сам:
val names = arrayOf("Alice", "Bob", "Charlie")

Это полный аналог Java String[] names = {"Alice", "Bob", "Charlie"};.

2. Создание пустого массива

Для пустого массива используйте emptyArray<String>():

val emptyNames: Array<String> = emptyArray()

3. Создание массива фиксированного размера (с заполнением)

Если нужно создать массив из N элементов, но значения будут присвоены позже, используйте конструктор Array(size) { initialValue }:

// Создаём массив из 10 строк, каждая равна null (для nullable-типа)
val names: Array<String?> = arrayOfNulls(10)
// Или с помощью конструктора:
val names2 = Array(10) { "" }  // все элементы — пустые строки
val names3 = Array(10) { index -> "Name #$index" } // динамическое заполнение

Важно: arrayOfNulls(10) возвращает Array<String?> (nullable-элементы), потому что иначе нельзя — массив не инициализирован. Если вам нужны не-null значения, используйте второй вариант с лямбдой.

4. Работа с массивом

Доступ по индексу и изменение элементов — как в Java:

val names = arrayOf("Alice", "Bob")
println(names[0]) // Alice
names[1] = "Robert"
println(names.joinToString()) // Alice, Robert

5. Взаимодействие с Java-кодом

Kotlin массивы Array<String> полностью совместимы с Java String[]. Если у вас есть Java-метод:

// Java
public void printNames(String[] names) { ... }

то из Kotlin вы можете вызвать его напрямую:

val kotlinArray = arrayOf("Alice", "Bob")
printNames(kotlinArray) // OK, компилятор автоматически преобразует

6. Примитивные массивы (для чисел)

Если вам нужен массив примитивных типов (Int, Double и т.д.), используйте специализированные классы: IntArray, DoubleArray, BooleanArray и т.д. Они работают быстрее и занимают меньше памяти, чем Array<Int>:

val intArray = intArrayOf(1, 2, 3)      // IntArray
val doubleArray = doubleArrayOf(1.0, 2.0) // DoubleArray
// Но для String нет примитивного типа, поэтому только Array<String>

Резюме

  • Java String[] → Kotlin Array<String>
  • Создание: arrayOf(...), Array(size) { ... }, arrayOfNulls(size)
  • Для чисел используйте IntArray, FloatArray и т.д.
  • Массивы полностью совместимы с Java-кодом.

Не путайте с List<String> — это неизменяемый список, а не массив. Если вам нужна изменяемая коллекция с динамическим размером, лучше использовать ArrayList или mutableListOf().

<<>>

Альтернативный подход: использование listOf и преобразование в массив

Если вы не уверены, что вам нужен именно массив, рассмотрите использование списков. В Kotlin списки используются гораздо чаще, чем массивы, потому что они гибче и имеют богатый API. Но если вы всё же должны передать Array<String> в Java-метод, вы можете легко преобразовать список в массив:

// Создаём список строк
val namesList = listOf("Alice", "Bob", "Charlie")

// Преобразуем в массив
val namesArray: Array<String> = namesList.toTypedArray()

// Теперь можно передать в Java-метод
printNames(namesArray)

Этот подход удобен, если вы сначала собираете данные динамически (например, в цикле), а потом передаёте их в Java-код. Для динамического сбора данных используйте mutableListOf():

val mutableList = mutableListOf<String>()
for (i in 1..10) {
    mutableList.add("Item $i")
}
val finalArray = mutableList.toTypedArray()

Недостаток: toTypedArray() создаёт новый массив, копируя все элементы. Если массив очень большой, это может быть накладно по памяти и времени. В таких случаях лучше сразу работать с массивом, используя Array(size) { ... }.