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>hasaddandremovefunctions, 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,CharArrayetc. 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 classentries), 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.