Cloning Lists in Kotlin: Deep vs Shallow Copy

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Cloning Lists in Kotlin: How to Avoid Messing Up with References?

\n\n

Imagine: you're writing a Kotlin application, processing a list of data, and suddenly the original array changes on its own. Sound familiar? Most likely, you just copied a reference, not the list itself. In this article, we'll cover all the legitimate ways to clone a list in Kotlin — from shallow copy to deep copy. No fluff, just code and explanations.

\n\n

This topic is inspired by a popular Stack Overflow question (over 200,000 views): "How to clone or copy a list in kotlin". Let's finally figure out how to properly copy a Kotlin list without losing data or losing your mind.

\n\n

Why Doesn't Simple Assignment Work?

\n\n

In Kotlin, as in Java, lists are reference types. If you write:

\n\n
val original = mutableListOf("A", "B", "C")\nval copy = original  // This is NOT a copy!\ncopy.add("D")\nprintln(original) // [A, B, C, D] — the original changed!
\n\n

You've simply created a second reference to the same object in memory. Any modification through copy will affect original. To avoid this, you need to use special methods for copying a Kotlin list.

\n\n

Top 5 Ways to Copy a List in Kotlin

\n\n

We'll cover all the main options: from simple toList() to manual deep copying. Choose the one that fits your task.

\n\n

1. toList() — The Simplest Way

\n\n

The toList() method creates a new immutable copy of the list. This is a shallow copy — the elements themselves are not duplicated, but the list structure becomes independent.

\n\n
val original = listOf("Kotlin", "Java", "Python")\nval copy = original.toList()\n\n// copy is a new object\nprintln(copy === original) // false — different references\nprintln(copy == original)  // true — same content
\n\n

Perfect for simple lists of strings or numbers. If you need a mutable copy, use toMutableList().

\n\n

2. toMutableList() — For Mutable Copies

\n\n

Want a copy you can modify? toMutableList() is your choice. It creates a new MutableList with the same elements.

\n\n
val original = listOf(1, 2, 3)\nval mutableCopy = original.toMutableList()\nmutableCopy.add(4)\n\nprintln(original)       // [1, 2, 3]\nprintln(mutableCopy)    // [1, 2, 3, 4] — original untouched
\n\n

This is the most popular way to clone a mutable list in Kotlin.

\n\n

3. ArrayList(collection) — Java Classic

\n\n

If you come from Java, this method will feel familiar. The ArrayList constructor takes another collection and copies its elements.

\n\n
val original = listOf("A", "B", "C")\nval arrayCopy = ArrayList(original)\narrayCopy[0] = "Z"\n\nprintln(original)    // [A, B, C]\nprintln(arrayCopy)   // [Z, B, C]
\n\n

Works quickly and predictably. But remember: this is also a shallow copy.

\n\n

4. map() — With Element Transformation

\n\n

If you need not just to copy but also to transform elements, use map(). It creates a new list based on the old one, applying a lambda to each element.

\n\n
val numbers = listOf(10, 20, 30)\nval doubled = numbers.map { it * 2 }\n\nprintln(numbers)  // [10, 20, 30]\nprintln(doubled)  // [20, 40, 60]
\n\n

For simple copying without changes, you can write numbers.map { it }, but that's redundant — better use toList().

\n\n

5. Deep Copy for Complex Objects

\n\n

All previous methods perform a shallow copy. If your list contains mutable objects (e.g., a data class with fields), modifying an object in the copy will affect the original:

Blogs

Book Recommendations