Unterschied zwischen Listen- und Array-Typen in Kotlin

189

Was ist der Unterschied zwischen Listund ArrayTypen?
Es scheint, dass mit ihnen dieselben Operationen ausgeführt werden können (Schleifen, Filterausdruck usw.). Gibt es Unterschiede im Verhalten oder in der Verwendung?

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
quelle

Antworten:

279

Arrays und Listen (dargestellt durch List<T>und ihr Subtyp MutableList<T>) weisen viele Unterschiede auf. Hier sind die wichtigsten:

  • Array<T>ist eine Klasse mit bekannter Implementierung: Es handelt sich um einen sequentiellen Speicherbereich mit fester Größe, in dem die Elemente gespeichert werden (und in JVM wird er durch ein Java-Array dargestellt ).

    List<T>und MutableList<T>sind Schnittstellen , die unterschiedlichen Implementierungen haben: ArrayList<T>, LinkedList<T>usw. Speicherrepräsentation und Operationen Logik der Listen in konkreter Implementierung definiert ist, beispielsweise in einer Indexierungs LinkedList<T>geht durch die Links und nimmt O (n) Zeit während ArrayList<T>speichert seine Elemente in einem dynamisch zugeordneten Array.

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
  • Array<T>ist veränderbar (kann durch einen Verweis darauf geändert werden), List<T>verfügt jedoch nicht über Änderungsmethoden (es handelt sich entweder um eine schreibgeschützte AnsichtMutableList<T> oder um eine unveränderliche Listenimplementierung ).

    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
  • Arrays haben eine feste Größe und können die Identität nicht erweitern oder verkleinern (Sie müssen ein Array kopieren, um die Größe zu ändern). In Bezug auf die Listen, MutableList<T>hat addund removefunktioniert, so dass es seine Größe erhöhen und verringern kann.

    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>ist invariant aufT ( Array<Int>ist nicht Array<Number>), das gleiche für MutableList<T>, ist aber List<T>kovariant ( List<Int>ist List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
  • Arrays sind für die Primitiven optimiert: Es gibt getrennte IntArray, DoubleArray, CharArrayetc. , die auf Java primitive Arrays abgebildet werden ( int[], double[], char[]), nicht boxed Einsen ( Array<Int>auf Java abgebildet Integer[]). In Listen sind Implementierungen im Allgemeinen nicht für Grundelemente optimiert, obwohl einige Bibliotheken (außerhalb von JDK) primitivoptimierte Listen bereitstellen.

  • List<T>und MutableList<T>sind zugeordnete Typen und haben ein spezielles Verhalten in der Java-Interoperabilität (Java List<T>wird von Kotlin entweder List<T>oder als gesehen MutableList<T>). Arrays werden ebenfalls zugeordnet, haben jedoch andere Regeln für die Java-Interoperabilität.

  • Bestimmte Array-Typen werden in Annotationen verwendet (primitive Arrays Array<String>und Arrays mit enum classEinträgen), und es gibt eine spezielle Array-Literal-Syntax für Annotationen . Listen und andere Sammlungen können nicht in Anmerkungen verwendet werden.

  • In Bezug auf die Verwendung empfiehlt es sich, Listen überall Arrays vorzuziehen, mit Ausnahme von leistungskritischen Teilen Ihres Codes. Die Argumentation ist dieselbe wie für Java .

Hotkey
quelle
26

Der Hauptunterschied zur Verwendungsseite besteht darin, dass Arrays eine feste Größe haben und (Mutable)Listihre Größe dynamisch anpassen können. Darüber hinaus Arrayist veränderlich, während Listnicht.

Weiterhin kotlin.collections.Listwird eine Schnittstelle unter anderem von implementiert java.util.ArrayList. Es wird auch erweitert kotlin.collections.MutableList, um verwendet zu werden, wenn eine Sammlung erforderlich ist, die Elementänderungen ermöglicht.

Auf der JVM-Ebene Arraywird durch Arrays dargestellt . ListAuf der anderen Seite wird dargestellt durch, java.util.Listda in Java keine unveränderlichen Sammlungsäquivalente verfügbar sind.

Miensol
quelle
Ich bin hier nicht ganz überzeugt. Was ist veränderlich Array? Nur es sind Elemente - das gleiche in der List. Die Größe von Listist ebenfalls festgelegt.
AndroidEx
1
@AndroidEx Folgendes wird kompiliert, val intArray = arrayOf(1,2,3); intArray[0] = 2dies jedoch nicht val intList = listOf(1,2,3); intList[0] = 2. Das hat Listzwar eine feste Größe, aber MutableListdas erweitert es nicht, daher ist es möglich, dass a bei nachfolgenden Anrufen val a:List<Int>anders meldet size.
Miensol
Wird empfohlen, Listoder zu verwenden ArrayList?
Igor Ganapolsky
2
@IgorGanapolsky Wenn Sie sich nicht für die konkrete Implementierung interessieren List(wahrscheinlich 99% der Fälle 🙂). Wenn Sie das tun kümmern uns um die Umsetzung Nutzung ArrayListoder LinkedListoder andere konkrete Umsetzung.
Miensol