ProgrammatieAndroid ontwikkelaar

Beschrijf het werkmechanisme van collecties in Kotlin: de verschillen tussen List, MutableList, Set, MutableSet, Map, MutableMap. Welke valkuilen kunnen zich voordoen bij hun gebruik? Geef codevoorbeelden.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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.

Voorbeeld code:

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:

  • Collecties zijn standaard niet-wijzigbaar.
  • Veel functies die lijsten van de standaardbibliotheek retourneren, retourneren List (en niet MutableList).
  • Het is belangrijk om bij het werken met collecties geen wijzigingen aan te brengen in die collecties die niet bedoeld zijn om gewijzigd te worden.

Misleidende vraag.

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!).

Voorbeelden van echte fouten door onbekendheid met de fijnere details van het onderwerp.


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 MutableList gedeclareerd, 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 mutableListOf gebruikt, 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.