Perbedaan antara jenis Daftar dan Array di Kotlin

192

Apa perbedaan antara Listdan Arrayjenis?
Tampaknya dapat melakukan operasi yang sama dengan mereka (loop, ekspresi filter, dll.), Apakah ada perbedaan perilaku atau penggunaan?

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
sumber

Jawaban:

281

Array dan daftar (diwakili oleh List<T>dan subtipe MutableList<T>) memiliki banyak perbedaan, berikut adalah yang paling signifikan:

  • Array<T>adalah kelas dengan implementasi yang diketahui: ini adalah wilayah memori ukuran tetap berurutan yang menyimpan item (dan pada JVM diwakili oleh Java array ).

    List<T>dan MutableList<T>adalah antarmuka yang memiliki implementasi yang berbeda: ArrayList<T>, LinkedList<T>dll representasi Memory dan operasi logika dari daftar didefinisikan dalam pelaksanaan beton, misalnya pengindeksan dalam LinkedList<T>melewati link dan mengambil O (n) waktu sedangkan ArrayList<T>toko item dalam array dialokasikan secara dinamis.

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
  • Array<T>bisa berubah (bisa diubah melalui referensi apa pun untuk itu), tetapi List<T>tidak memiliki metode modifikasi (baik tampilan baca-sajaMutableList<T> atau implementasi daftar yang tidak dapat diubah ).

    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
  • Array memiliki ukuran tetap dan tidak dapat memperluas atau mengecilkan identitas penahan (Anda perlu menyalin array untuk mengubah ukurannya). Adapun daftar, MutableList<T>memiliki adddan removefungsinya, sehingga dapat menambah dan mengurangi ukurannya.

    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>adalah invarian padaT ( Array<Int>tidak Array<Number>), yang sama untuk MutableList<T>, tetapi List<T>adalah kovarian ( List<Int>adalah List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
  • Array dioptimalkan untuk primitif: ada yang terpisah IntArray, DoubleArray, CharArraydll yang dipetakan ke Jawa array primitif ( int[], double[], char[]), bukan kotak yang ( Array<Int>dipetakan ke Jawa Integer[]). Daftar pada umumnya tidak memiliki implementasi yang dioptimalkan untuk primitif, meskipun beberapa perpustakaan (di luar JDK) menyediakan daftar yang dioptimalkan primitif.

  • List<T>dan MutableList<T>yang dipetakan jenis dan memiliki perilaku khusus di interoperabilitas Jawa (Jawa List<T>terlihat dari Kotlin baik sebagai List<T>atau MutableList<T>). Array juga dipetakan, tetapi mereka memiliki aturan interoperabilitas Java lainnya.

  • Jenis array tertentu digunakan dalam anotasi (array primitif Array<String>,, dan array dengan enum classentri), dan ada sintaks literal array khusus untuk anotasi . Daftar dan koleksi lainnya tidak dapat digunakan dalam anotasi.

  • Mengenai penggunaan, praktik yang baik adalah lebih suka menggunakan daftar daripada array di mana-mana kecuali untuk bagian-bagian penting dari kode Anda, alasannya sama dengan Java .

hotkey
sumber
26

Perbedaan utama dari sisi penggunaan adalah bahwa Array memiliki ukuran tetap sementara (Mutable)Listdapat menyesuaikan ukurannya secara dinamis. Apalagi Arraybisa berubah sedangkanList tidak.

Selanjutnya kotlin.collections.Listadalah antarmuka yang diimplementasikan antara lain oleh java.util.ArrayList. Ini juga diperpanjang olehkotlin.collections.MutableList untuk digunakan ketika koleksi yang memungkinkan untuk modifikasi barang diperlukan.

Pada level jvm Arraydiwakili oleh array . Listdi sisi lain diwakili oleh java.util.Listkarena tidak ada koleksi setara yang tersedia di Jawa.

miensol
sumber
Saya tidak sepenuhnya yakin di sini. Apa yang bisa berubah Array? Hanya elemen - yang sama di List. Ukurannya Listjuga tetap.
AndroidEx
1
@AndroidEx berikut ini akan dikompilasi val intArray = arrayOf(1,2,3); intArray[0] = 2sementara ini tidak akan val intList = listOf(1,2,3); intList[0] = 2. The Listmemang memiliki ukuran tetap tetapi MutableListyang memanjang tidak maka adalah mungkin bahwa val a:List<Int>akan melaporkan yang berbeda sizepada panggilan berikutnya.
miensol
Apakah disarankan untuk menggunakan Listatau ArrayList?
IgorGanapolsky
2
@IgorGanapolsky Jika Anda tidak peduli dengan penggunaan implementasi konkret List(mungkin 99% dari kasus 🙂). Jika Anda peduli dengan penggunaan implementasi ArrayListatau LinkedListatau implementasi konkret lainnya.
miensol