Diferencia entre tipos de lista y matriz en Kotlin
¿ Cuál es la diferencia entre List
y Array
tipos?
Parece que se pueden realizar las mismas operaciones con ellos (bucles, expresión de filtro, etc.), ¿hay alguna diferencia en el comportamiento o el uso?
val names1 = listOf("Joe","Ben","Thomas")
val names2 = arrayOf("Joe","Ben","Thomas")
for (name in names1)
println(name)
for (name in names2)
println(name)
Las matrices y listas (representadas por List<T>
y su subtipo MutableList<T>
) tienen muchas diferencias, estas son las más importantes:
Array<T>
es una clase con implementación conocida: es una región de memoria secuencial de tamaño fijo que almacena los elementos (y en JVM está representada por una matriz Java ).List<T>
yMutableList<T>
son interfaces que tienen diferentes implementaciones:ArrayList<T>
,LinkedList<T>
etc. La representación de la memoria y la lógica de operaciones de las listas se definen en una implementación concreta, por ejemplo, la indexación en aLinkedList<T>
pasa por los enlaces y toma un tiempo O(n) mientras queArrayList<T>
almacena sus elementos en una matriz asignada dinámicamente.val list1: List<Int> = LinkedList<Int>() val list2: List<Int> = ArrayList<Int>()
Array<T>
es mutable (se puede cambiar a través de cualquier referencia a él), peroList<T>
no tiene métodos de modificación (es una vista de solo lecturaMutableList<T>
o una implementación de lista inmutable ).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
Las matrices tienen un tamaño fijo y no pueden expandirse ni reducirse conservando la identidad (es necesario copiar una matriz para cambiar su tamaño). En cuanto a las listas,
MutableList<T>
tieneadd
yremove
funciones, para que pueda aumentar y reducir su tamaño.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>
es invariante enT
(Array<Int>
no esArray<Number>
), lo mismo paraMutableList<T>
, peroList<T>
es covariante (List<Int>
esList<Number>
).val a: Array<Number> = Array<Int>(0) { 0 } // won't compile val l: List<Number> = listOf(1, 2, 3) // OK
Las matrices están optimizadas para primitivas: hay
IntArray
,DoubleArray
,CharArray
etc. separadas que se asignan a matrices primitivas de Java (int[]
,double[]
,char[]
), no encajonadas (Array<Int>
se asignan a JavaInteger[]
). Las listas en general no tienen implementaciones optimizadas para primitivas, aunque algunas bibliotecas (fuera de JDK) proporcionan listas optimizadas para primitivas.List<T>
yMutableList<T>
son tipos mapeados y tienen un comportamiento especial en la interoperabilidad de Java (JavaList<T>
se ve desde Kotlin comoList<T>
oMutableList<T>
). Las matrices también se asignan, pero tienen otras reglas de interoperabilidad de Java.Ciertos tipos de matrices se utilizan en las anotaciones (matrices primitivas
Array<String>
y matrices conenum class
entradas), y existe una sintaxis literal de matriz especial para las anotaciones . Las listas y otras colecciones no se pueden utilizar en anotaciones.En cuanto al uso, una buena práctica es preferir el uso de listas en lugar de matrices en todas partes, excepto en las partes críticas de rendimiento de su código; el razonamiento es el mismo que para Java .
La principal diferencia desde el punto de vista del uso es que las matrices tienen un tamaño fijo mientras que (Mutable)List
pueden ajustar su tamaño dinámicamente. Además Array
es mutable mientras que List
no lo es.
Además kotlin.collections.List
hay una interfaz implementada entre otros por java.util.ArrayList
. También se extiende para kotlin.collections.MutableList
usarse cuando se necesita una colección que permita la modificación de elementos.
En el nivel de jvm, Array
está representado por matrices . List
por otro lado, está representado por, java.util.List
ya que no hay equivalentes de colecciones inmutables disponibles en Java.