# How to Create a Kotlin List: The Simplest Methods Explained

> Discover the simplest methods to create a Kotlin list. Learn to use listOf() for immutable lists and mutableListOf() for modifiable collections in Kotlin.

- Repository: [JetBrains/kotlin](https://github.com/jetbrains/kotlin)
- Tags: tutorial
- Published: 2026-02-14

---

**Use the `listOf()` factory function to create an immutable list, or `mutableListOf()` when you need a modifiable collection.**

The Kotlin standard library provides concise, type-safe factory functions for list creation. In the JetBrains/kotlin repository, the `listOf` function is implemented in [`libraries/stdlib/src/kotlin/collections/Collections.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/collections/Collections.kt) as the idiomatic entry point for instantiating read-only lists without ceremony.

## The listOf Implementation

The simplest way to create a Kotlin list leverages the top-level `listOf` function defined in the standard library. As implemented in [`libraries/stdlib/src/kotlin/collections/Collections.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/collections/Collections.kt), this function accepts a variable number of arguments and returns a `List<T>`:

```kotlin
public fun <T> listOf(vararg elements: T): List<T> = if (elements.isEmpty()) emptyList() else elements.asList()

```

This implementation optimizes for the empty case by returning a shared singleton from [`EmptyList.kt`](https://github.com/JetBrains/kotlin/blob/main/EmptyList.kt), while non-empty lists delegate to `elements.asList()`, which typically returns a `java.util.ArrayList` on the JVM platform.

## Immutable vs. Mutable Lists

Kotlin distinguishes between read-only and mutable collections at the type level. Choosing the correct factory function depends on whether you need to modify the list after creation.

### Creating Immutable Lists with listOf

**`listOf`** returns a `List<T>` that cannot be modified. Attempting to call mutating methods like `add()` or `remove()` throws `UnsupportedOperationException`. This is the preferred default when you don't need to change the collection contents.

```kotlin
// Simple immutable list
val numbers = listOf(1, 2, 3, 4)  // List<Int>
println(numbers)  // [1, 2, 3, 4]

// Type inference with explicit empty list
val emptyStrings = listOf<String>()  // List<String>

```

### Creating Mutable Lists with mutableListOf

When you need to add, remove, or reorder elements, use **`mutableListOf`** (also defined in [`Collections.kt`](https://github.com/JetBrains/kotlin/blob/main/Collections.kt)). This returns a `MutableList<T>` backed by an `ArrayList`:

```kotlin
val mutable = mutableListOf("a", "b")  // MutableList<String>
mutable.add("c")
println(mutable)  // [a, b, c]

```

## Empty Lists and Performance Optimizations

The Kotlin standard library optimizes memory usage for empty collections. When you call `listOf()` without arguments, or `emptyList()`, the function returns a singleton instance defined in [`libraries/stdlib/src/kotlin/collections/EmptyList.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/collections/EmptyList.kt). This prevents unnecessary object allocation when creating multiple empty lists throughout your application.

## Practical Code Examples

Here are complete patterns for creating Kotlin lists in real-world scenarios:

```kotlin
// Factory function in a generic context
fun <T> printAll(items: List<T>) {
    for (item in items) println(item)
}

// Passing a newly created list
printAll(listOf("Kotlin", "Java", "Scala"))

// Creating from existing elements with spread operator
val existing = arrayOf(1, 2, 3)
val combined = listOf(0, *existing, 4)  // [0, 1, 2, 3, 4]

// Null-safe list creation with explicit type
val possiblyEmpty: List<String> = listOf()

```

## Summary

- **`listOf()`** is the idiomatic way to create Kotlin lists when you don't need to modify the contents after creation.
- **`mutableListOf()`** returns a `MutableList` backed by `ArrayList` for collections that require updates.
- **Empty lists** reuse a singleton instance for memory efficiency.
- On the **JVM platform**, non-empty lists created via `listOf` use `java.util.ArrayList` as the underlying implementation.

## Frequently Asked Questions

### What is the difference between listOf and arrayListOf in Kotlin?

**`listOf`** returns a `List` interface with read-only semantics, while **`arrayListOf`** specifically returns an `ArrayList` instance (mutable). Both allow modification of contents, but `listOf` restricts the interface to read-only operations. According to the source code in [`Collections.kt`](https://github.com/JetBrains/kotlin/blob/main/Collections.kt), `arrayListOf` exists primarily for Java interoperability when you specifically need the `ArrayList` concrete type rather than just the `MutableList` interface.

### Is listOf in Kotlin truly immutable?

**`listOf`** returns a read-only view of the list, but immutability depends on the elements themselves. The collection structure cannot change (no add/remove), but if the list contains mutable objects, those objects can still be modified. For true immutable collections, combine `listOf` with immutable data classes or use Kotlin's immutable collections library.

### How do I create an empty list in Kotlin?

Use **`listOf()`** with explicit type parameters or **`emptyList()`**: `val empty = listOf<String>()` or `val empty = emptyList<String>()`. Both return the same singleton `EmptyList` instance defined in the standard library, making this approach memory-efficient for creating multiple empty collections.

### What collection type does listOf return on the JVM?

On the **JVM**, `listOf` returns a `List<T>` backed by `java.util.ArrayList` for non-empty collections, as seen in the implementation where `elements.asList()` creates the underlying list. For empty lists, it returns the singleton `EmptyList` object. This platform-specific detail is abstracted away by the Kotlin standard library, ensuring consistent behavior across platforms.