Array<T>
это класс с известной реализацией: это последовательная область памяти фиксированного размера, хранящая элементы (а в JVM она представлена массивом Java ).
List<T>
и MutableList<T>
являются интерфейсами, которые имеют разные реализации: ArrayList<T>
и LinkedList<T>
т. д. Представление в памяти и логика операций списков определены в конкретной реализации, например, индексирование в a LinkedList<T>
проходит по ссылкам и занимает O (n) времени, тогда как ArrayList<T>
его элементы хранятся в динамически распределенном массиве.
val list1: List<Int> = LinkedList<Int>()
val list2: List<Int> = ArrayList<Int>()
Array<T>
является изменяемым (его можно изменить с помощью любой ссылки на него), но List<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
т.д. , которые отображаются на 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 .
Array
? Только это элементы - то же самое вList
. РазмерList
также фиксирован.val intArray = arrayOf(1,2,3); intArray[0] = 2
а это не будетval intList = listOf(1,2,3); intList[0] = 2
.List
Действительно имеет фиксированный размер , ноMutableList
который распространяется не значит , что это возможно , чтоval a:List<Int>
сообщит разныеsize
при последующих вызовах.List
илиArrayList
?List
(вероятно, в 99% случаев 🙂). Если вы действительно заботятся об использовании реализацииArrayList
илиLinkedList
или какой - либо другой реализации конкретной.