Avatar ·

Как в Kotlin объявить массив строк, как в Java String[]? Ищу аналог

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

В Java я привык писать:

String[] names = new String[]{"Alice", "Bob", "Charlie"};

Или, если массив пустой:

String[] names = new String[10];

Теперь я пытаюсь сделать то же самое в Kotlin. Я попробовал несколько вариантов, но ни один не работает или выдаёт ошибки компиляции:

// Вариант 1: Просто скопировал Java-синтаксис
var names: String[] = arrayOf("Alice", "Bob") // Ошибка: "String[] is not a type"

// Вариант 2: Попробовал через Array
var names: Array<String> = ["Alice", "Bob"] // Ошибка: "Type mismatch"

// Вариант 3: Создание пустого массива
var names = new String[10] // Ошибка: "Unresolved reference: new"

Я понимаю, что Kotlin — это не Java, но мне кажется, что такая базовая вещь, как массив строк, должна быть интуитивно понятной. Подскажите, пожалуйста, правильный синтаксис. Мне нужно:

  • Создать массив строк с фиксированными значениями.
  • Создать пустой массив строк определённого размера.
  • Получить доступ к элементам по индексу и изменить их.

Заранее спасибо за помощь!

<<>>

Правильный способ объявления массива строк в Kotlin

В Kotlin нет синтаксиса String[], как в Java. Вместо этого используются обобщённые типы Array<String> или специализированные примитивные массивы. Вот как решить вашу задачу:

1. Создание массива с фиксированными значениями

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

val names: Array<String> = arrayOf("Alice", "Bob", "Charlie")
// Или с выведением типа:
val names = arrayOf("Alice", "Bob", "Charlie")

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

Для этого используйте конструктор Array(size) с лямбдой-инициализатором. Если вам нужен массив с null значениями (как в Java с new String[10]), укажите тип как Array<String?>:

val emptyNames: Array<String?> = Array(10) { null }
// Массив из 10 элементов, каждый равен null

Если вы хотите массив из пустых строк (не null), передайте лямбду, возвращающую пустую строку:

val emptyStrings: Array<String> = Array(10) { "" }

3. Доступ и изменение элементов

В Kotlin доступ по индексу работает через квадратные скобки, как в Java:

val names = arrayOf("Alice", "Bob", "Charlie")
println(names[0]) // Alice
names[1] = "Robert" // Изменяем элемент
println(names[1]) // Robert

4. Специализированные массивы для примитивов

Для строк Array<String> — это нормально. Но если вы работаете с числами, Kotlin предлагает оптимизированные типы: IntArray, DoubleArray, BooleanArray и т.д. Для строк такого нет, потому что String — это ссылочный тип.

5. Распространённые ошибки и их решение

  • Ошибка: var names: String[] — В Kotlin нет синтаксиса String[]. Используйте Array<String>.
  • Ошибка: var names = ["Alice", "Bob"] — Это синтаксис списка (List), а не массива. Для списка это сработает, но массив требует arrayOf().
  • Ошибка: new String[10] — В Kotlin нет оператора new для массивов. Используйте Array(10) { ... }.

6. Полный пример для вашего случая

fun main() {
    // Массив с данными
    val names = arrayOf("Alice", "Bob", "Charlie")
    
    // Пустой массив на 5 элементов (все null)
    val buffer: Array<String?> = Array(5) { null }
    
    // Заполняем буфер
    for (i in names.indices) {
        buffer[i] = names[i]
    }
    
    // Выводим результат
    println(buffer.joinToString()) // Alice, Bob, Charlie, null, null
}

Важное замечание: В Kotlin массивы — это изменяемые коллекции фиксированного размера. Если вам нужна динамическая коллекция, рассмотрите MutableList<String>:

val mutableList = mutableListOf("Alice", "Bob")
mutableList.add("Charlie") // Можно добавлять элементы
<<>>

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

Хотя ответ выше полностью решает ваш вопрос, стоит упомянуть, что в Kotlin массивы используются реже, чем в Java. Идиоматичный Kotlin предпочитает неизменяемые списки (List) или изменяемые списки (MutableList).

Если вам не нужна фиксированная длина и вы не работаете с низкоуровневым кодом (например, JNI или оптимизация производительности), используйте списки:

// Неизменяемый список (аналог Java Arrays.asList)
val names: List<String> = listOf("Alice", "Bob", "Charlie")

// Изменяемый список (аналог Java ArrayList)
val mutableNames: MutableList<String> = mutableListOf("Alice", "Bob")
mutableNames.add("Charlie") // OK
mutableNames[0] = "Alicia"  // OK

Преимущества списков перед массивами:

  • Более гибкие (можно добавлять/удалять элементы).
  • Богатая стандартная библиотека функций (filter, map, forEach и т.д.).
  • Лучшая совместимость с Java-коллекциями.

Если вам всё же нужен именно массив (например, для взаимодействия с Java-библиотекой, которая ожидает String[]), используйте arrayOf() или toTypedArray() для преобразования списка в массив:

val list = listOf("Alice", "Bob")
val array: Array<String> = list.toTypedArray()