Warum hat Kotlin uns add, remove und put "weggenommen"? Wir klären ein für alle Mal auf
\n\nWenn Sie jemals in Java programmiert und dann zu Kotlin gewechselt sind, sind Sie sicherlich auf diesen Moment leichter Verwirrung gestoßen. Sie erstellen eine List, möchten ein Element hinzufügen – schreiben .add() – und die Entwicklungsumgebung markiert es rot. Oder Sie versuchen, einen Wert in eine Map mit .put() einzufügen – und wieder ein Fehler.
Kommt Ihnen bekannt vor? Und wie! Die Frage "Kotlin's List missing "add", "remove", Map missing "put", etc?" auf Stack Overflow hat tausende Aufrufe und Dutzende Kommentare gesammelt. Das ist ein echter Stolperstein für Anfänger, und selbst erfahrene Entwickler ertappen sich manchmal bei dem Gedanken: "Wo sind nur meine gewohnten Methoden?"
\n\nIn diesem Artikel werden wir nicht nur diese Frage beantworten. Wir zeigen, wie die Philosophie von Kotlin diesen "Mangel" in Ihren größten Vorteil verwandelt. Sie lernen die Best Practices für die Arbeit mit Collections im Jahr 2025 kennen, werden den richtigen Collection-Typ auswählen und sich nicht mehr zwischen listOf und mutableListOf verirren. Los geht's!
Was ist der Kern? Unveränderlichkeit als Lebensstil
\n\nDas Erste, was man verstehen muss: Kotlin wurde von Grund auf als eine Sprache entwickelt, die sicheren und vorhersagbaren Code fördert. Eines der Hauptprinzipien ist die Unveränderlichkeit (Immutability) als Standard.
\n\nIn Java gibt es ein einziges Interface List, und es enthält immer die Methoden add(), remove(), set() und so weiter. Selbst wenn Sie eine Liste mit List.of() (Java 9+) erstellen, haben Sie immer noch Zugriff auf diese Methoden – sie werfen lediglich eine Ausnahme zur Laufzeit. Das ist umständlich und unsicher.
Kotlin ist einen anderen Weg gegangen. Es unterteilt Collections in zwei Typen:
\n\n- \n
- Unveränderliche (schreibgeschützt):
List,Set,Map– sie haben keine Methoden, die den Inhalt ändern. \n - Veränderliche (mutable):
MutableList,MutableSet,MutableMap– diese haben alle bekanntenadd,remove,put. \n
Genau deshalb hat listOf(1, 2, 3) keine Methode .add(). Es gibt eine unveränderliche Liste zurück. mutableListOf(1, 2, 3) hingegen gibt eine veränderliche zurück, und diese hat .add().
Klingt logisch? Schauen wir uns den Code an.
\n\nBeispiele: Was funktioniert und was nicht
\n\nHier ist eine klassische Situation, die Anfänger verwirrt:
\n\n// ❌ Fehler! List hat kein add()\nval fruits = listOf("apple", "banana")\nfruits.add("orange") // Kompilierungsfehler\n\n// ✅ Richtig: MutableList verwenden\nval mutableFruits = mutableListOf("apple", "banana")\nmutableFruits.add("orange") // Jetzt funktioniert es!\nprintln(mutableFruits) // [apple, banana, orange]\n\n\nBei Map die gleiche Geschichte:
\n\n// ❌ Fehler! Map hat kein put()\nval capitals = mapOf("Russia" to "Moscow", "France" to "Paris")\ncapitals.put("Germany", "Berlin") // Kompilierungsfehler\n\n// ✅ Richtig: MutableMap verwenden\nval mutableCapitals = mutableMapOf("Russia" to "Moscow", "France" to "Paris")\nmutableCapitals.put("Germany", "Berlin")\n// Oder noch kürzer:\nmutableCapitals["Germany"] = "Berlin"\nprintln(mutableCapitals) // {Russia=Moscow, France=Paris, Germany=Berlin}\n\n\nBeachten Sie: Für MutableMap können Sie die Operator-Klammern [] verwenden – das ist im Grunde put() unter der Haube. Sehr praktisch!
Aber warum? Warum macht Kotlin uns das Leben so schwer?
\n\nAuf den ersten Blick scheint dies eine unnötige Kopfschmerzquelle zu sein. Warum sollte man sich zwei Arten von Collections merken? In Wirklichkeit ist es eine geniale Lösung. Hier sind die drei Hauptgründe:
\n\n1. Typsicherheit
\nDer Compiler überwacht nun, dass Sie nicht versehentlich eine Liste ändern, die unveränderlich sein sollte