Diferencia entre los tipos de lista y matriz en Kotlin

192

¿Cuál es la diferencia entre Listy los Arraytipos?
Parece que puede hacer 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)
Daniel Hári
fuente

Respuestas:

281

Las matrices y las listas (representadas por List<T>y su subtipo MutableList<T>) tienen muchas diferencias, estas son las más significativas:

  • 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 de Java ).

    List<T>y MutableList<T>son interfaces que tienen diferentes implementaciones: ArrayList<T>, LinkedList<T>etc. representación de la memoria y las operaciones de la lógica de las listas se definen en la aplicación concreta, por ejemplo, la indexación en un LinkedList<T>pasa a través de los enlaces y toma tiempo O (n), mientras que ArrayList<T>almacena sus artículos 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), pero List<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 se pueden expandir ni reducir la retención de identidad (debe copiar una matriz para cambiar su tamaño). En cuanto a las listas, MutableList<T>tiene addy removefunciones, 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 es Array<Number>), lo mismo para MutableList<T>, pero List<T>es covariante ( List<Int>es List<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 optimizados para las primitivas: existen por separado IntArray, DoubleArray, CharArrayetc., que se asignan a las matrices primitivas Java ( int[], double[], char[]), no en caja unos ( Array<Int>se asigna a Java Integer[]). Las listas en general no tienen implementaciones optimizadas para primitivas, aunque algunas bibliotecas (fuera de JDK) proporcionan listas optimizadas para primitivas.

  • List<T>y MutableList<T>son tipos mapeados y tienen un comportamiento especial en la interoperabilidad de Java ( List<T>Kotlin ve a Java como List<T>o MutableList<T>). Las matrices también se asignan, pero tienen otras reglas de interoperabilidad Java.

  • Ciertos tipos de matriz se usan en anotaciones (matrices primitivas Array<String>y matrices con enum classentradas), y hay una sintaxis literal de matriz especial para las anotaciones . Las listas y otras colecciones no se pueden usar en anotaciones.

  • En cuanto al uso, una buena práctica es preferir usar listas en lugar de matrices en todas partes, excepto para las partes críticas del rendimiento de su código, el razonamiento es el mismo que para Java .

tecla de acceso directo
fuente
26

La principal diferencia con respecto al uso es que las matrices tienen un tamaño fijo mientras que (Mutable)Listpueden ajustar su tamaño dinámicamente. Además Arrayes mutable mientras queList que no lo es.

Además kotlin.collections.Listes una interfaz implementada entre otras por java.util.ArrayList. También se extiende porkotlin.collections.MutableList para usarse cuando se necesita una colección que permita la modificación de elementos.

En el nivel jvm Arrayestá representado por matrices . Listpor otro lado está representado por java.util.Listya que no hay equivalentes de colecciones inmutables disponibles en Java.

miensol
fuente
No estoy completamente convencido aquí. ¿Qué hay en mutable Array? Solo son elementos, lo mismo en el List. El tamaño de Listtambién es fijo.
AndroidEx
1
@AndroidEx lo siguiente se compilará val intArray = arrayOf(1,2,3); intArray[0] = 2mientras que esto no val intList = listOf(1,2,3); intList[0] = 2. De Listhecho, tiene un tamaño fijo, pero lo MutableListque lo extiende no lo hace, por lo tanto, es posible que un val a:List<Int>informe sea diferente sizeen llamadas posteriores.
miensol
¿Se recomienda usar Listo ArrayList?
IgorGanapolsky
2
@IgorGanapolsky Si no le importa el uso de implementación concreta List(probablemente el 99% de los casos 🙂). Si lo hace la atención sobre el uso de la aplicación ArrayListo LinkedList, o cualquier otra aplicación concreta.
miensol