ProgrammingAndroid Developer

Describe the mechanism of collections in Kotlin: differences between List, MutableList, Set, MutableSet, Map, MutableMap. What pitfalls can arise from their use? Provide code examples.

Pass interviews with Hintsage AI assistant

Answer.

Kotlin offers two types of collections: immutable and mutable.

  • List — an immutable list. Elements cannot be added/removed.
  • MutableList — a mutable list: elements can be added and removed.
  • Set — an immutable set (unique elements).
  • MutableSet — a mutable set.
  • Map — an associative array (key-value), immutable.
  • MutableMap — a mutable associative array.

Code example:

val fruits: List<String> = listOf("Apple", "Banana", "Cherry") val mutableFruits: MutableList<String> = mutableListOf("Apple", "Banana") mutableFruits.add("Cherry") val fruitSet: Set<String> = setOf("Apple", "Banana") // Uniqueness of elements val mutableFruitSet: MutableSet<String> = mutableSetOf("Apple", "Banana") mutableFruitSet.add("Cherry") val scores: Map<String, Int> = mapOf("Tom" to 80, "Jane" to 90) val mutableScores: MutableMap<String, Int> = mutableMapOf("Tom" to 80) mutableScores["Jane"] = 90

Nuances:

  • Collections are immutable by default.
  • Many functions returning lists from the standard library return List (not MutableList).
  • When working with collections, it is important not to modify those that were not intended for changes.

Trick question.

If you have a function that takes List<T> as a parameter, can you somehow modify this list inside the function?

Answer: No, if the parameter is of type List<T>, you cannot add/remove elements inside the function. But if a MutableList<T> is actually passed, it can be cast to this type (which introduces risk):

fun modifyList(list: List<String>) { if (list is MutableList) { list.add("Another") // Works if the original collection is mutable } }

This is not recommended, as it violates the contract (List should be immutable!).

Examples of real errors due to a lack of knowledge of the nuances of the topic.


Story

In a large project, a function that took List<Customer> was used, and an attempt was made to add a new element inside the function. The compilation error (add/clear/remove are not defined for List) was only discovered during review, as a mutable list was required for data transformation.


Story

A collection was declared as MutableList, but was passed across several threads without synchronization. As a result, competing modifications occurred, leading to "ConcurrentModificationException" and corrupting the state of the list. The error was sought for a long time, as thread-safety was not considered.


Story

In one of the services dealing with database query results, mutableListOf was used, and then a reference was given outside. External code mistakenly cleared the list. As a result, empty data reached the user, as references were not cloned and mutable collections were modified outside the business logic layer.