Differenza tra i tipi di elenco e di matrice in Kotlin


192

Qual'è la differenza tra Liste Arraytypes?
Sembra che possano fare le stesse operazioni con loro (loop, espressione di filtro, ecc.), C'è qualche differenza nel comportamento o nell'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)

Risposte:


281

Le matrici e gli elenchi (rappresentati da List<T>e il suo sottotipo MutableList<T>) presentano molte differenze, ecco le più significative:

  • Array<T>è una classe con un'implementazione nota: è una regione di memoria sequenziale a dimensione fissa che memorizza gli elementi (e su JVM è rappresentata dall'array Java ).

    List<T>e MutableList<T>sono interfacce che hanno diverse implementazioni: ArrayList<T>, LinkedList<T>ecc rappresentazione di memoria e operazioni logiche di liste sono definite nella realizzazione concreta, per esempio l'indicizzazione in un LinkedList<T>passa attraverso i collegamenti e prende O (n) che ArrayList<T>memorizza i suoi articoli in un array allocato dinamicamente.

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
  • Array<T>è mutabile (può essere modificato mediante qualsiasi riferimento ad esso), ma List<T>non ha metodi di modifica (è una visualizzazione di sola letturaMutableList<T> o un'implementazione dell'elenco immutabile ).

    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
  • Le matrici hanno dimensioni fisse e non possono espandere o ridurre l'identità di conservazione (è necessario copiare una matrice per ridimensionarla). Per quanto riguarda le liste, MutableList<T>ha adde removefunzioni, in modo che possa aumentare e ridurne le dimensioni.

    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>è invariante suT ( Array<Int>non è Array<Number>), lo stesso per MutableList<T>, ma List<T>è covariante ( List<Int>è List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
  • Matrici sono ottimizzati per primitive: ci sono separati IntArray, DoubleArray, CharArrayecc, che sono mappati Java array primitivi ( int[], double[], char[]), non inscatolato quelli ( Array<Int>viene mappato Java Integer[]). Gli elenchi in generale non hanno implementazioni ottimizzate per le primitive, sebbene alcune librerie (al di fuori di JDK) forniscano elenchi ottimizzati per le primitive.

  • List<T>e MutableList<T>sono tipi mappati e hanno un comportamento speciale nell'interoperabilità di Java (Java List<T>viene visto da Kotlin come o List<T>o MutableList<T>). Anche gli array sono mappati, ma hanno altre regole di interoperabilità Java.

  • Alcuni tipi di array vengono utilizzati nelle annotazioni (array primitivi Array<String>e array con enum classvoci) e c'è una speciale sintassi letterale dell'array per le annotazioni . Elenchi e altre raccolte non possono essere utilizzati nelle annotazioni.

  • Per quanto riguarda l'utilizzo, la buona pratica è quella di preferire l'utilizzo di elenchi su array ovunque tranne che per le parti critiche delle prestazioni del codice, il ragionamento è lo stesso di quello per Java .


26

La principale differenza dal lato dell'utilizzo è che le matrici hanno dimensioni fisse mentre (Mutable)Listpossono regolare le loro dimensioni in modo dinamico. Inoltre Arrayè mutevole considerando cheList non lo è.

Inoltre kotlin.collections.Listè un'interfaccia implementata tra l'altro da java.util.ArrayList. È anche esteso dakotlin.collections.MutableList per essere utilizzato quando è necessaria una raccolta che consenta la modifica degli articoli.

A livello jvm Arrayè rappresentato da array . Listd'altra parte è rappresentato da java.util.Listpoiché non ci sono equivalenti di raccolte immutabili disponibili in Java.


Non sono completamente convinto qui. Cosa c'è di mutevole in Array? Solo i suoi elementi - lo stesso nel List. Anche la dimensione di Listè fissa.
AndroidEx

1
@AndroidEx verrà compilato quanto segue, val intArray = arrayOf(1,2,3); intArray[0] = 2mentre ciò non avverrà val intList = listOf(1,2,3); intList[0] = 2. Il Listeffettivamente ha una dimensione fissa, ma MutableListche lo estende non è quindi possibile che un val a:List<Int>testerà diverso sizenelle chiamate successive.
miensol,

Si consiglia di utilizzare Listo ArrayList?
IgorGanapolsky,

2
@IgorGanapolsky Se non ti interessa l'uso concreto dell'implementazione List(probabilmente il 99% dei casi 🙂). Se fate attenzione circa l'uso di attuazione ArrayListo di LinkedListo di qualsiasi altra applicazione concreta.
Miensol,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.