Question
How can I copy a list in Kotlin?
For example, I am currently using:
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Is there a simpler or more idiomatic way to create a copy of a list in Kotlin?
Short Answer
By the end of this page, you will understand how to copy lists in Kotlin, when to use toList() or toMutableList(), the difference between read-only and mutable lists, and what it really means to make a shallow copy of a collection.
Concept
In Kotlin, copying a list usually means creating a new list object that contains the same elements as an existing list.
This matters because you often want to avoid changing the original list by mistake. For example, if one part of your program modifies a list, you may not want those changes to affect another part.
The most common ways to copy a list in Kotlin are:
val copy1 = original.toList()
val copy2 = original.toMutableList()
These create a new collection containing the same items.
Read-only vs mutable lists
Kotlin distinguishes between:
List<T>: read-only viewMutableList<T>: can be changed
So the copy method you choose depends on what you need:
- Use
toList()when you want a read-only copy - Use
toMutableList()when you want a copy you can change
Important detail: shallow copy
List copying in Kotlin is usually a shallow copy.
That means:
- the list container is new
- the elements inside are the same references if they are objects
Example:
data class User(var name: String)
val original = mutableListOf(User("Ava"))
val copied = original.toMutableList()
copied[].name =
println(original[].name)
Mental Model
Think of a list like an egg carton.
- The carton is the list itself.
- The eggs are the elements inside it.
When you use toList() or toMutableList(), Kotlin gives you a new carton, but usually puts the same eggs into it.
So:
- changing the carton structure, such as adding or removing eggs, affects only that new carton
- changing an egg itself affects both cartons if they hold the same egg object
This is the key idea behind shallow copying.
Syntax and Examples
The most idiomatic Kotlin ways to copy a list are:
val readOnlyCopy = original.toList()
val mutableCopy = original.toMutableList()
Example 1: Copy as read-only
val series = listOf("Dark", "Lost", "Sherlock")
val copiedSeries = series.toList()
println(copiedSeries) // [Dark, Lost, Sherlock]
Use this when you only need to read values.
Example 2: Copy as mutable
val series = listOf("Dark", "Lost", "Sherlock")
val selectedSeries = series.toMutableList()
selectedSeries.add("Severance")
println(series) // [Dark, Lost, Sherlock]
println(selectedSeries) // [Dark, Lost, Sherlock, Severance]
Here, selectedSeries is a new mutable list, so adding an item does not change series.
Example 3: Your current approach
val selectedSeries = mutableListOf<String>()
selectedSeries.addAll(series)
Step by Step Execution
Consider this example:
val original = mutableListOf("A", "B", "C")
val copy = original.toMutableList()
copy.add("D")
println(original)
println(copy)
Step by step
-
originalis created as a mutable list:["A", "B", "C"] -
copy = original.toMutableList()creates a new mutable list with the same elements.At this point:
original=["A", "B", "C"]copy=["A", "B", "C"]
-
copy.add("D")adds a new element only tocopy. -
Final result:
original=
Real World Use Cases
Copying lists is useful in many real programs.
UI state updates
In Android or desktop apps, you may copy a list before modifying it so the original UI state stays unchanged.
val updatedItems = currentItems.toMutableList()
updatedItems.add(newItem)
Filtering user selections
If a user selects items from a master list, you may want a separate editable copy.
val selectedProducts = allProducts.toMutableList()
API data processing
You might receive a list from a repository layer and copy it before sorting or modifying it.
val sortedUsers = users.toMutableList()
sortedUsers.sortBy { it.name }
Defensive programming
Sometimes you copy incoming collections so outside code cannot accidentally affect your internal state.
class Report(items: List<String>) {
private val safeItems = items.toList()
}
Batch operations
A script may duplicate a list before removing invalid items, while preserving the original input for logging or auditing.
Real Codebase Usage
In real Kotlin projects, developers often use list copying as part of safer state management and cleaner function design.
Common pattern: make a mutable working copy
A common workflow is:
val workingList = source.toMutableList()
workingList.removeIf { it.isBlank() }
This keeps the original data unchanged.
Defensive copies in constructors and setters
When classes receive collections from outside, developers often copy them:
class Playlist(songs: List<String>) {
private val songsCopy = songs.toList()
}
This reduces accidental shared state.
Early-return and validation workflows
A list may be copied only after validation passes:
fun prepareTags(tags: List<String>?): List<String> {
if (tags == null) return emptyList()
if (tags.isEmpty()) return emptyList()
return tags.toList()
}
Copy before sorting
Sorting a mutable copy is common when the original order must remain intact:
Common Mistakes
1. Assuming assignment creates a copy
This is a very common mistake.
val original = mutableListOf("A", "B")
val copy = original
copy.add("C")
println(original) // [A, B, C]
copy = original does not create a new list. Both variables point to the same list.
2. Using toList() and expecting a mutable list
val original = listOf("A", "B")
val copy = original.toList()
// copy.add("C") // Error
Use toMutableList() if you need to add or remove items.
3. Forgetting that copies are usually shallow
data class Item(var value: Int)
val original = mutableListOf(Item(1))
val copy = original.toMutableList()
copy[0].value = 99
println(original[0].value)
Comparisons
| Approach | What it does | Mutable? | Typical use |
|---|---|---|---|
val b = a | Copies the reference only | Same as original | When you intentionally want the same list |
a.toList() | Creates a new read-only list | No | Safe reading, defensive copy |
a.toMutableList() | Creates a new mutable list | Yes | Modify the copy without changing the original |
mutableListOf<T>().apply { addAll(a) } | Creates a mutable copy manually | Yes | Less concise alternative |
a.map { it } | Creates a new list by iterating |
Cheat Sheet
// Read-only copy
val copy1 = original.toList()
// Mutable copy
val copy2 = original.toMutableList()
// Manual mutable copy
val copy3 = mutableListOf<String>()
copy3.addAll(original)
Rules
val b = adoes not copy the listtoList()returns a read-only list view/copy for normal usagetoMutableList()returns a mutable copy- Standard list copying is usually shallow
- If elements are mutable objects, both lists can still point to the same objects
Quick choice guide
- Need to read only:
toList() - Need to modify the copy:
toMutableList() - Need changed values too:
map { ... }
Example
val original = listOf("x", "y")
val copy = original.toMutableList()
copy.add("z")
Edge case
If the list contains mutable objects, copying the list does not clone the objects inside it.
FAQ
How do I copy a list in Kotlin?
Use toList() for a read-only copy or toMutableList() for a mutable copy.
What is the idiomatic way to clone a list in Kotlin?
The most idiomatic approach is usually:
val copy = original.toMutableList()
or
val copy = original.toList()
Does val copy = original make a new list?
No. It only copies the reference, so both variables point to the same list.
What is the difference between toList() and toMutableList() in Kotlin?
toList() gives you a read-only list. toMutableList() gives you a list you can change.
Does copying a list in Kotlin also copy the objects inside it?
No, not usually. Standard copying is shallow, so object elements are shared.
Is addAll() wrong for copying a list?
No. It works correctly. It is just more verbose than toMutableList() when your goal is simply to copy the list.
Mini Project
Description
Build a small Kotlin program that manages a list of favorite TV series. The program should start with an original list, create a separate copy for user-selected series, then modify only the copied list. This demonstrates the practical difference between referencing a list and creating an actual copy.
Goal
Create a copied list that can be changed without affecting the original list.
Requirements
- Create an original list of at least three series names.
- Make a mutable copy of that list.
- Add one new series to the copied list.
- Print both the original list and the copied list.
- Show that the original list stays unchanged.
Keep learning
Related questions
Accessing Kotlin Extension Functions from Java
Learn how Kotlin extension functions are compiled and how to call them correctly from Java with clear examples and common pitfalls.
Android AlarmManager Example: Scheduling Tasks with AlarmManager
Learn how to use Android AlarmManager to schedule tasks, set alarms, and handle broadcasts with a simple beginner example.
Android Foreground Service Notification Channels in Kotlin
Learn why startForeground fails on Android 8.1 and how to create a valid notification channel for foreground services in Kotlin.