Kotlin biedt twee soorten collecties: immutable (niet-wijzigbaar) en mutable (wijzigbaar).
List — een niet-wijzigbare lijst. Elementen kunnen niet worden toegevoegd of verwijderd.MutableList — een wijzigbare lijst: elementen kunnen worden toegevoegd en verwijderd.Set — een niet-wijzigbare set (unieke elementen).MutableSet — een wijzigbare set.Map — een associatieve array (sleutel-waarde), niet-wijzigbaar.MutableMap — een wijzigbare associatieve array.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") // Uniciteit van elementen 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
Fijnere details:
List (en niet MutableList).Als je een functie hebt die
List<T>als parameter accepteert, kun je deze lijst op een of andere manier binnen de functie wijzigen?
Antwoord: Nee, als de parameter van het type List<T> is, kunnen binnen de functie geen elementen worden toegevoegd of verwijderd. Maar als er feitelijk een MutableList<T> is doorgegeven, kan deze worden gecast naar dit type (wat risico's met zich meebrengt):
fun modifyList(list: List<String>) { if (list is MutableList) { list.add("Another") // Werkt als de oorspronkelijke collectie wijzigbaar is } }
Dit wordt niet aanbevolen, omdat het contract wordt geschonden (List moet niet-wijzigbaar zijn!).
Verhaal
In een groot project werd een functie gebruikt die
List<Customer>accepteerde, en probeerden ze een nieuw element toe te voegen binnen de functie. De compilatiefout (add/clear/remove zijn niet gedefinieerd voor List) werd pas tijdens de review ontdekt, omdat een wijzigbare lijst vereist was voor gegevensconversie.
Verhaal
De collectie werd als
MutableListgedeclareerd, maar zonder synchronisatie aan verschillende threads doorgegeven. Dit leidde tot concurrerende wijzigingen, wat resulteerde in een "ConcurrentModificationException" en beschadiging van de status van de lijst. De fout werd lang gezocht, omdat thread-safety niet in overweging was genomen.
Verhaal
In een van de services die resultaten van database-query's verwerkten, werd
mutableListOfgebruikt, en daarna werd de referentie naar buiten gegeven. Externe code wist per ongeluk de lijst schoon. Als gevolg hiervan bereikte de gebruiker lege gegevens, omdat de referenties niet gekloond werden en wijzigbare collecties buiten de lagen van de bedrijfslogica werden gemodificeerd.