ProgramGuru

Read-only and mutable lists

Read-only and mutable lists

A class register grows as students arrive. Kotlin List exposes ordered read operations, while MutableList also exposes changes. A read-only view is an API restriction, not proof that no other reference can change the same collection.

What you’ll learn

  • Distinguish a read-only live view from a snapshot.
  • Choose intentional mutation and safe access.

Read-only and mutable lists in the example

  1. Mutable register

    A class register grows as students arrive.

    Mutable register
  2. Read-only live view

    Use listOf for ordinary read-only list construction and mutableListOf when updates are part of the task.

    Read-only live view
  3. Earlier snapshot

    The read-only view still observes the same mutable list, now containing three names.

    Earlier snapshot
The read-only view still observes the same mutable list, now containing three names. The snapshot contains two. FirstOrNull returns Diya. The val binding permits add because it does not reassign the list reference.

Understand read-only and mutable lists

Use listOf for ordinary read-only list construction and mutableListOf when updates are part of the task. Subscripts use zero-based positions and can throw out of bounds. firstOrNull handles an empty list. toList creates a snapshot of the elements, but does not deeply clone referenced objects.

Connect this to arrays and indexed access and nullable types and safe calls.

Follow read-only and mutable lists

Save the complete source as Main.kt and use the Kotlin/JVM environment. No separate input file is needed.

Kotlin/JVM · complete program

fun main() {
  val students = mutableListOf("Diya", "Saira")
  val view: List<String> = students
  val snapshot = students.toList()
  students.add("Noor")
  println(view.size)
  println(snapshot.size)
  println(students.firstOrNull())
}

Expected output

3
2
Diya

Follow the execution

The read-only view still observes the same mutable list, now containing three names. The snapshot contains two. FirstOrNull returns Diya. The val binding permits add because it does not reassign the list reference.

Try this in the Kotlin compiler by pasting the complete program.

Practice: Read-only and mutable lists

Your task: Is view guaranteed to remain unchanged forever?

Kotlin/JVM · complete program

fun main() {
  val students = mutableListOf("Diya", "Saira")
  val view: List<String> = students
  val snapshot = students.toList()
  students.add("Noor")
  println(view.size)
  println(snapshot.size)
  println(students.firstOrNull())
}

Worked answer

No. Another reference can mutate its underlying collection; read-only access and immutable contents are different promises.

Read-only and mutable lists: the important boundary

Choose whether callers need a live view or a snapshot and document that contract. Removing an element changes later positions. Avoid using a list index as a permanent student identity.

Check your understanding

Is view guaranteed to remain unchanged forever?
Choose one answer. You can try again.

Answer and explanation

No.

No. Another reference can mutate its underlying collection; read-only access and immutable contents are different promises.

Check the practical consequence

A MutableList is exposed through List. What can you promise?
Choose one answer. You can try again.

Answer and explanation

This interface restricts writes through that reference, but other aliases may still mutate backing data.

Distinguish a read-only live view from a snapshot. Choose intentional mutation and safe access.

Read-only and mutable lists: what to keep in mind

No. Another reference can mutate its underlying collection; read-only access and immutable contents are different promises. Choose whether callers need a live view or a snapshot and document that contract.

Further reading: official Kotlin documentation for this topic.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Maps and key-based lookup →