ความแตกต่างระหว่างชนิดรายการและอาร์เรย์ใน Kotlin


192

ความแตกต่างระหว่างListและArrayประเภทคืออะไร?
ดูเหมือนว่าสามารถทำการดำเนินการเดียวกันกับพวกเขา (ลูปการแสดงออกของตัวกรอง ฯลฯ ) มีความแตกต่างในพฤติกรรมหรือการใช้งานหรือไม่?

val names1 = listOf("Joe","Ben","Thomas")
val names2 = arrayOf("Joe","Ben","Thomas")

for (name in names1)
    println(name)
for (name in names2)
    println(name)

คำตอบ:


281

อาร์เรย์และรายการ (แสดงโดยList<T>และชนิดย่อยMutableList<T>) มีความแตกต่างมากมายนี่คือสิ่งที่สำคัญที่สุด:

  • Array<T>เป็นคลาสที่มีการใช้งานที่รู้จัก: มันเป็นขอบเขตหน่วยความจำคงที่ขนาดต่อเนื่องที่จัดเก็บรายการ (และใน JVM จะแสดงโดยอาร์เรย์ Java )

    List<T>และMutableList<T>มีอินเตอร์เฟซที่มีการใช้งานที่แตกต่างกันArrayList<T>, LinkedList<T>ฯลฯ เป็นตัวแทนหน่วยความจำและตรรกะการดำเนินงานของรายการที่กำหนดไว้ในการดำเนินงานที่เป็นรูปธรรมเช่นการจัดทำดัชนีในLinkedList<T>ไปผ่านการเชื่อมโยงและใช้เวลา O (n) เวลาในขณะที่ArrayList<T>ร้านค้ารายการในอาร์เรย์จัดสรร

    val list1: List<Int> = LinkedList<Int>()
    val list2: List<Int> = ArrayList<Int>()
  • Array<T>ไม่แน่นอน (สามารถเปลี่ยนแปลงได้ผ่านการอ้างอิงใด ๆ ) แต่List<T>ไม่มีวิธีการแก้ไข (เป็นมุมมองแบบอ่านMutableList<T>อย่างเดียวหรือการใช้งานรายการที่ไม่เปลี่ยนรูป )

    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
  • อาร์เรย์มีขนาดคงที่และไม่สามารถขยายหรือย่อขนาดการเก็บข้อมูลได้ (คุณต้องคัดลอกอาร์เรย์เพื่อปรับขนาด) สำหรับรายการที่MutableList<T>มีaddและremoveฟังก์ชั่นเพื่อให้สามารถเพิ่มและลดขนาดของมัน

    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>คือค่าคงที่T ( Array<Int>ไม่ใช่Array<Number>) ค่าเดียวกันสำหรับMutableList<T>แต่List<T>เป็นค่าแปรปรวนร่วม ( List<Int>คือList<Number>)

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
  • อาร์เรย์จะเหมาะสำหรับพื้นฐาน: มีแยกต่างหากIntArray, DoubleArray, CharArrayฯลฯ ซึ่งได้รับการแมปไป Java อาร์เรย์ดั้งเดิม ( int[], double[], char[]) ไม่บรรจุกล่องคน ( Array<Int>ถูกแมปไปของ Java Integer[]) รายการโดยทั่วไปไม่มีการปรับใช้ที่เหมาะสำหรับการใช้พื้นฐานแม้ว่าบางไลบรารี (นอก JDK) จะมีรายการที่ปรับให้เหมาะสมแบบดั้งเดิม

  • List<T>และMutableList<T>เป็นประเภทที่แมปและมีพฤติกรรมพิเศษในการทำงานร่วมกันของ Java (Java List<T>ถูกมองจาก Kotlin เป็นอย่างใดอย่างหนึ่งList<T>หรือMutableList<T>) อาร์เรย์จะถูกแมปด้วยเช่นกัน แต่มีกฎอื่น ๆของการทำงานร่วมกันของ Java

  • มีการใช้ประเภทอาร์เรย์บางประเภทในคำอธิบายประกอบ (อาร์เรย์ดั้งเดิมArray<String>และอาร์เรย์ที่มีenum classรายการ) และมีไวยากรณ์ตัวอักษรพิเศษสำหรับการเพิ่มความคิดเห็น รายการและคอลเล็กชันอื่น ๆ ไม่สามารถใช้ในการเพิ่มความคิดเห็น

  • ขณะที่การใช้งานการปฏิบัติที่ดีคือการต้องการใช้รายการมากกว่าอาร์เรย์ทุกที่ยกเว้นสำหรับผลการดำเนินงานส่วนที่สำคัญของรหัสของคุณให้เหตุผลเป็นเดียวกันกับที่สำหรับ Java


26

ข้อแตกต่างที่สำคัญจากด้านการใช้งานคืออาร์เรย์มีขนาดคงที่ในขณะที่(Mutable)Listสามารถปรับขนาดแบบไดนามิกได้ ยิ่งกว่านั้นArrayสามารถเปลี่ยนแปลงได้ในขณะที่Listไม่ใช่

นอกจากkotlin.collections.Listเป็นอินเตอร์เฟซการดำเนินการอื่น ๆ java.util.ArrayListในกลุ่มโดย นอกจากนี้ยังขยายโดยkotlin.collections.MutableListที่จะใช้เมื่อมีการรวบรวมรายการที่ต้องการสำหรับการแก้ไขรายการ

ในระดับ JVM Arrayเป็นตัวแทนจากอาร์เรย์ Listในทางตรงกันข้ามมีการแสดงjava.util.Listเนื่องจากไม่มีคอลเลกชันที่ไม่เปลี่ยนรูปแบบที่มีอยู่ใน Java


ฉันไม่มั่นใจอย่างเต็มที่ที่นี่ สิ่งที่อยู่ในที่ไม่แน่นอนArray? เพียง แต่มันเป็นองค์ประกอบ - Listเดียวกันใน ขนาดของListยังได้รับการแก้ไข
AndroidEx

1
@AndroidEx ต่อไปนี้จะรวบรวมในขณะนี้จะไม่val intArray = arrayOf(1,2,3); intArray[0] = 2 แน่นอนมีขนาดคงที่ แต่ซึ่งทอดตัวมันไม่ได้ด้วยเหตุนี้มันเป็นไปได้ว่าจะรายงานที่แตกต่างกันในการโทรตามมา val intList = listOf(1,2,3); intList[0] = 2ListMutableListval a:List<Int>size
miensol

แนะนำให้ใช้ListหรือArrayList?
IgorGanapolsky

2
@IgorGanapolsky หากคุณไม่สนใจการใช้งานที่เป็นรูปธรรมList(อาจเป็น 99% ของคดี🙂) หากคุณสนใจเกี่ยวกับการใช้งานการใช้งานArrayListหรือLinkedListการใช้งานอย่างเป็นรูปธรรมอื่น ๆ
miensol
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.