Array<T>
jest klasą o znanej implementacji: jest to sekwencyjny region pamięci o stałym rozmiarze, przechowujący elementy (w JVM jest reprezentowany przez tablicę Java ).
List<T>
i MutableList<T>
interfejsy, które mają różne implementacje: ArrayList<T>
, LinkedList<T>
itp reprezentacja Pamięć i operacje logika listach są zdefiniowane w konkretnej implementacji, np indeksowanie w sposób LinkedList<T>
przechodzi przez linki i zajmuje O (n), natomiast czas ArrayList<T>
przechowuje swoje pozycje w dynamicznie przydzielonego tablicy.
val list1: List<Int> = LinkedList<Int>()
val list2: List<Int> = ArrayList<Int>()
Array<T>
jest zmienny (można go zmienić przez dowolne odniesienie do niego), ale List<T>
nie ma metod modyfikujących (jest to widok tylko do odczytuMutableList<T>
lub niezmienna implementacja listy ).
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
Tablice mają ustalony rozmiar i nie mogą rozszerzać ani zmniejszać tożsamości zachowującej (musisz skopiować tablicę, aby zmienić jej rozmiar). Co do list, MutableList<T>
ma add
i remove
funkcje, dzięki czemu może zwiększać i zmniejszać swój rozmiar.
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>
jest niezmienny dlaT
( Array<Int>
nie jest Array<Number>
), to samo dla MutableList<T>
, ale List<T>
jest kowariantem ( List<Int>
jest List<Number>
).
val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
val l: List<Number> = listOf(1, 2, 3) // OK
Tablice są zoptymalizowane dla prymitywów: istnieją oddzielne IntArray
, DoubleArray
, CharArray
itd., Które są odwzorowane na Java prymitywnych tablic ( int[]
, double[]
, char[]
), nie ramkach z nich ( Array<Int>
jest mapowany do Javy Integer[]
). Listy ogólnie nie mają implementacji zoptymalizowanych dla prymitywów, chociaż niektóre biblioteki (poza JDK) zapewniają listy zoptymalizowane dla prymitywów.
List<T>
i MutableList<T>
są odwzorowane rodzajów i mają szczególne zachowanie interoperacyjności Java (Java List<T>
widać z Kotlin jako albo List<T>
albo MutableList<T>
). Tablice są również mapowane, ale mają inne zasady współdziałania Java.
Niektóre typy tablic są używane w adnotacjach (prymitywne tablice Array<String>
i tablice z enum class
wpisami), a dla adnotacji istnieje specjalna składnia dosłowna . Listy i inne kolekcje nie mogą być używane w adnotacjach.
Jeśli chodzi o użycie, dobrą praktyką jest preferowanie używania list zamiast tablic wszędzie, z wyjątkiem krytycznych pod względem wydajności części kodu, rozumowanie jest takie samo jak w przypadku Javy .
Array
? Tylko jego elementy - to samo wList
. RozmiarList
jest również ustalony.val intArray = arrayOf(1,2,3); intArray[0] = 2
podczas gdy nie będzie to możliweval intList = listOf(1,2,3); intList[0] = 2
.List
Rzeczywiście ma stały rozmiar, aleMutableList
która rozciąga się stąd, że nie jest to możliwe, żeval a:List<Int>
zgłosi innysize
na kolejnych połączeń.List
lubArrayList
?List
(prawdopodobnie 99% przypadków 🙂). Jeśli zależy Ci na implementacji, skorzystaj z niejArrayList
lubLinkedList
innej konkretnej implementacji.