List
和Array
类型之间的区别?它们似乎可以执行相同的操作(循环、筛选表达式等),但在行为或使用上有什么区别吗?< /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)
数组和列表(由List<T>
及其子类型MutableList<T>
表示)有许多不同之处,以下是其中最重要的几点:
Array<T>
is a class with known implementation: it's a sequential fixed-size memory region storing the items (and on JVM it is represented by Java array).
List<T>
and MutableList<T>
are interfaces which have different implementations: ArrayList<T>
, LinkedList<T>
etc. Memory representation and operations logic of lists are defined in concrete implementation, e.g. indexing in a LinkedList<T>
goes through the links and takes O(n) time whereas ArrayList<T>
stores its items in a dynamically allocated array.
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.
(Mutable)List
可以动态调整其大小。此外,Array
是可变的,而 List
不可变。kotlin.collections.List
是一个接口,被实现在其他类中,包括 java.util.ArrayList
。它也被 kotlin.collections.MutableList
扩展,用于需要允许项目修改的集合。Array
由 数组 表示。另一方面,List
则由 java.util.List
表示,因为 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
equals
和 hashCode
函数,而使用列表时则不需要。 - Kylaaa解释一个复杂的对象
// lets define a data class
data class Color(var name : String)
// lets define all 3 - array, list and mutableList for this Color object
val array = arrayOf(Color("Red"))
val list = listOf(Color("Red"))
val mutableList = mutableListOf(Color("Red"))
array.add(Color("Green")) // Not Possible - cannot change size
array[0] = Color("Green") // Possible - array object can be changed
array[0].name = "Green" // Possible - object modification allowed by its class
list.add(Color("Green")) // Not Possible - cannot change size
list[0] = Color("Green") // Not Possible - list object cannot be changed
list[0].name = "Green" // Possible - object modification allowed by its class
mutableList.add(Color("Green")) // Possible - can change size
mutableList[0] = Color("Green") // Possible - can change object
mutableList[0].name = "Green" // Possible - object modification allowed by its class
结论:
注意:这并未指定对象本身的可变性。即如果数据类具有某个属性为可变(var),则可以修改该属性。
Array
中可变的是什么?只有它的元素 -List
中也是一样的。List
的大小也是固定的。 - AndroidExval intArray = arrayOf(1,2,3); intArray[0] = 2
,然而以下代码编译不会通过:val intList = listOf(1,2,3); intList[0] = 2
。虽然List
具有固定的大小,但是继承它的MutableList
并没有,因此一个val a:List<Int>
在后续调用时可能会报告不同的size
。 - miensolList
还是ArrayList
更好? - IgorGanapolskyList
(大概99%的情况下都可以用)。如果你关心实现细节,可以使用ArrayList
或LinkedList
或其他具体的实现。 - miensol