Kotlin中List和Array类型的区别

ListArray类型有什么区别?< br > 它似乎可以做相同的操作(循环,过滤器表达式等..),有什么不同的行为或使用?< / p >

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


for (name in names1)
println(name)
for (name in names2)
println(name)
121876 次浏览

与使用方面的主要区别是数组有固定的大小,而(Mutable)List可以动态调整它们的大小。此外,Array是可变的,而List不是。

此外,kotlin.collections.List是由java.util.ArrayList实现的接口。它还被kotlin.collections.MutableList扩展,当需要允许项修改的集合时使用。

在jvm级别,Array数组表示。另一方面,Listjava.util.List表示,因为在Java中没有可用的不可变集合等价物。

数组和列表(由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> is mutable (it can be changed through any reference to it), but List<T> doesn't have modifying methods (it is either read-only view of MutableList<T> or an immutable list implementation).

    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 have fixed size and cannot expand or shrink retaining identity (you need to copy an array to resize it). As to the lists, MutableList<T> has add and remove functions, so that it can increase and reduce its size.

    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> is invariant on T (Array<Int> is not Array<Number>), the same for MutableList<T>, but List<T> is covariant (List<Int> is List<Number>).

    val a: Array<Number> = Array<Int>(0) { 0 } // won't compile
    val l: List<Number> = listOf(1, 2, 3) // OK
    
  • Arrays are optimized for primitives: there are separate IntArray, DoubleArray, CharArray etc. which are mapped to Java primitive arrays (int[], double[], char[]), not boxed ones (Array<Int> is mapped to Java's Integer[]). Lists in general do not have implementations optimized for primitives, though some libraries (outside JDK) provide primitive-optimized lists.

  • List<T> and MutableList<T> are mapped types and have special behaviour in Java interoperability (Java's List<T> is seen from Kotlin as either List<T> or MutableList<T>). Arrays are also mapped, but they have other rules of Java interoperability.

  • Certain array types are used in annotations (primitive arrays, Array<String>, and arrays with enum class entries), and there's a special array literal syntax for annotations. Lists and other collections cannot be used in annotations.

  • As to the usage, good practice is to prefer using lists over arrays everywhere except for performance critical parts of your code, the reasoning is the same to that for Java.

除了以上,身份比较也有所不同:

val l1 = listOf("a")
val l2 = listOf("a")
var x = (l1 == l2) // => true


val a1 = arrayOf("a")
val a2 = arrayOf("a")
var y = (a1 == a2) // => false