Подтвердить что ты не робот

Разница между типами List и Array в Котлине

В чем разница между типами List и Array?
Кажется, что с ними могут выполняться такие же операции (циклы, выражение фильтра и т.д.), Есть ли разница в поведении или использовании?

val names1 = listOf("Joe","Ben","Thomas")
val names2 = arrayOf("Joe","Ben","Thomas")

for (name in names1)
    println(name)
for (name in names2)
    println(name)
4b9b3361

Ответ 1

Массивы и списки (представленные List<T> и его подтипом MutableList<T>) имеют много различий, вот наиболее значимые из них:

  • Array<T> - это класс с известной реализацией: это последовательная область памяти фиксированного размера, в которой хранятся элементы (а в JVM она представлена массивом Java).

    List<T> и MutableList<T> являются интерфейсами, которые имеют разные реализации: ArrayList<T>, LinkedList<T> и т.д. Представление в памяти и логика операций списков определяются в конкретной реализации, например, выполняется индексация в LinkedList<T> ссылки и занимают O (n) времени, тогда как ArrayList<T> хранит свои элементы в динамически размещаемом массиве.

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
    
  • Array<T> является изменяемым (его можно изменить с помощью любой ссылки на него), но List<T> не имеет модифицирующих методов (это либо представление MutableList<T> только для MutableList<T> либо реализация неизменяемого списка).

    val a = arrayOf(1, 2, 3)
    a[0] = a[1] // OK
    
    val l = listOf(1, 2, 3)
    l[0] = l[1] // doesn't compile
    
    val m = mutableListOf(1, 2, 3)
    m[0] = m[1] // OK
    
  • Массивы имеют фиксированный размер и не могут расширять или уменьшать сохраняющуюся идентичность (вам нужно скопировать массив, чтобы изменить его размер). Что касается списков, MutableList<T> имеет функции add и remove, так что он может увеличивать и уменьшать свой размер.

    val a = arrayOf(1, 2, 3)
    println(a.size) // will always be 3 for this array
    
    val l = mutableListOf(1, 2, 3)
    l.add(4)
    println(l.size) // 4
    
  • Array<T> является инвариантом для T (Array<Int> не является Array<Number>), то же самое для MutableList<T>, но List<T> является ковариантным (List<Int> является List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
    
  • Массивы оптимизированы для примитивов: есть отдельные IntArray, DoubleArray, CharArray и т. DoubleArray, CharArray сопоставляются с массивами примитивов Java (int[], double[], char[]), а не в штучной упаковке (Array<Int> сопоставляется с Java Integer[]). Как правило, списки не имеют реализаций, оптимизированных для примитивов, хотя некоторые библиотеки (за пределами JDK) предоставляют списки, оптимизированные для примитивов.

  • List<T> и MutableList<T> являются отображенными типами и имеют особое поведение в совместимости с Java (Java List<T> рассматривается Kotlin как List<T> или MutableList<T>). Массивы также отображаются, но у них есть другие правила взаимодействия Java.

  • Определенные типы массивов используются в аннотациях (примитивные массивы, Array<String> и массивы с записями enum class), и существует специальный синтаксис литерала массива для аннотаций. Списки и другие коллекции не могут быть использованы в аннотациях.

  • Что касается использования, хорошей практикой является предпочтение использования списков над массивами везде, за исключением критических с точки зрения производительности частей вашего кода, аргументация та же, что и для Java.

Ответ 2

Основное отличие от использования стороны заключается в том, что Arrays имеют фиксированный размер, а (Mutable)List могут динамически изменять их размер. Более того, Array является изменяемым, тогда как List не является.

Более того kotlin.collections.List - это интерфейс, реализованный среди других java.util.ArrayList. Он также расширяется kotlin.collections.MutableList, который будет использоваться, когда нужны коллекции, которые позволяют изменять элемент.

На уровне jvm Array представлен массивами. List с другой стороны представлен java.util.List, поскольку в Java нет неизменяемых эквивалентов коллекций.

Ответ 3

** В общем, различия между типами List и Array: **

List<...>:

только для чтения.

Array<...>:

Вы можете изменить это, или добавить что-то.