Différence entre les types List et Array dans Kotlin

192

Quelle est la différence entre Listet Arraytypes?
Il semble pouvoir faire les mêmes opérations avec eux (boucles, expression de filtre, etc.), y a-t-il une différence de comportement ou d'utilisation?

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
la source

Réponses:

281

Les tableaux et les listes (représentés par List<T>et son sous-type MutableList<T>) présentent de nombreuses différences, voici les plus significatives:

  • Array<T>est une classe avec une implémentation connue: c'est une région mémoire séquentielle de taille fixe stockant les éléments (et sur JVM, elle est représentée par un tableau Java ).

    List<T>et MutableList<T>sont des interfaces qui ont différentes implémentations: ArrayList<T>, LinkedList<T>etc. logique de représentation de la mémoire et le fonctionnement des listes sont définies dans la mise en œuvre concrète, par exemple , l' indexation dans un LinkedList<T>passe par les liens et prend O (n) tandis que ArrayList<T>stocke ses éléments dans un tableau alloué dynamiquement.

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
  • Array<T>est modifiable (il peut être modifié via n'importe quelle référence), mais List<T>n'a pas de méthodes de modification (il s'agit d'une vue en lecture seuleMutableList<T> ou d'une implémentation de liste immuable ).

    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
  • Les tableaux ont une taille fixe et ne peuvent pas étendre ou réduire en conservant l'identité (vous devez copier un tableau pour le redimensionner). Quant aux listes, MutableList<T>a addet removefonctions, afin qu'il puisse augmenter et réduire sa taille.

    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>est invariant surT ( Array<Int>n'est pas Array<Number>), pareil pour MutableList<T>, mais List<T>est covariant ( List<Int>est List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
  • Les tableaux sont optimisés pour les primitives: il sont séparés IntArray, DoubleArray, CharArrayetc. , qui sont mis en correspondance avec les tableaux Java primitives ( int[], double[], char[]), pas boxed les ( Array<Int>est mis en correspondance de Java Integer[]). Les listes en général n'ont pas d'implémentations optimisées pour les primitives, bien que certaines bibliothèques (en dehors de JDK) fournissent des listes optimisées pour les primitives.

  • List<T>et MutableList<T>sont des types mappés et ont un comportement spécial dans l'interopérabilité Java (Java List<T>est vu de Kotlin comme l'un List<T>ou l' autre MutableList<T>). Les tableaux sont également mappés, mais ils ont d' autres règles d'interopérabilité Java.

  • Certains types de tableaux sont utilisés dans les annotations (tableaux primitifs Array<String>et tableaux avec enum classentrées), et il existe une syntaxe littérale de tableau spéciale pour les annotations . Les listes et autres collections ne peuvent pas être utilisées dans les annotations.

  • En ce qui concerne l'utilisation, la bonne pratique est de préférer utiliser des listes sur des tableaux partout, sauf pour les parties critiques de performances de votre code, le raisonnement est le même que pour Java .

touche de raccourci
la source
26

La principale différence du côté de l'utilisation est que les tableaux ont une taille fixe tout en (Mutable)Listpouvant ajuster leur taille dynamiquement. De plus, il Arrayest mutable alors qu'il Listne l'est pas.

De plus, kotlin.collections.Listune interface est implémentée entre autres par java.util.ArrayList. Il est également étendu par kotlin.collections.MutableListpour être utilisé lorsqu'une collection permettant la modification d'un élément est nécessaire.

Au niveau jvm Arrayest représenté par des tableaux . Listd'autre part est représenté par java.util.Listcar il n'y a pas d'équivalents de collections immuables disponibles en Java.

miensol
la source
Je ne suis pas entièrement convaincu ici. Qu'est-ce qui est mutable Array? Seuls ses éléments - le même dans le List. La taille de Listest également fixe.
AndroidEx
1
@AndroidEx ce qui suit sera compilé val intArray = arrayOf(1,2,3); intArray[0] = 2alors que ce ne sera pas le cas val intList = listOf(1,2,3); intList[0] = 2. Le a en Listeffet une taille fixe mais MutableListqui ne l'étend pas, il est donc possible que un val a:List<Int>rapportera différent sizelors des appels suivants.
miensol
Est-il recommandé d'utiliser Listou ArrayList?
IgorGanapolsky
2
@IgorGanapolsky Si vous ne vous souciez pas de l'utilisation de l'implémentation concrète List(probablement 99% des cas 🙂). Si vous faites attention sur l' utilisation de la mise en œuvre ArrayListou LinkedListou toute autre mise en œuvre du béton.
miensol