Arrays and lists (represented by List<T>
and its subtype MutableList<T>
) have many differences, here are the most significant ones:
-
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>
andMutableList<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 aLinkedList<T>
goes through the links and takes O(n) time whereasArrayList<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), butList<T>
doesn’t have modifying methods (it is either read-only view ofMutableList<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>
hasadd
andremove
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 onT
(Array<Int>
is notArray<Number>
), the same forMutableList<T>
, butList<T>
is covariant (List<Int>
isList<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’sInteger[]
). Lists in general do not have implementations optimized for primitives, though some libraries (outside JDK) provide primitive-optimized lists. -
List<T>
andMutableList<T>
are mapped types and have special behaviour in Java interoperability (Java’sList<T>
is seen from Kotlin as eitherList<T>
orMutableList<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 withenum 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.