Kurz: Kotlin unterscheidet schreibgeschützte (List, Set, Map) und veränderbare (MutableList …) Collections.
Teil des Kurses Kotlin
Listen
Kotlin unterscheidet schreibgeschützte (List, Set, Map) und veränderbare (MutableList …) Collections.
fun main() {
val feste = listOf("Apfel", "Birne", "Kirsche") // nicht veränderbar
val liste = mutableListOf(5, 3, 9)
liste.add(1)
liste.add(0, 42)
liste.remove(9)
liste[1] = 7
println("$feste ${feste.size} ${feste[0]} ${feste.first()} ${feste.last()}")
println(liste)
println(liste.sorted())
println(liste.sortedDescending())
println(liste.reversed())
println(liste.contains(7))
println(7 in liste)
println(liste.indexOf(7))
println(liste.getOrNull(10))
println(liste.subList(1, 3))
println(liste + listOf(100))
println(liste - 7)
println(emptyList<Int>().isEmpty())
for ((i, x) in liste.withIndex()) print("$i:$x ")
println()
}Ausgabe:
[Apfel, Birne, Kirsche] 3 Apfel Apfel Kirsche
[42, 7, 3, 1]
[1, 3, 7, 42]
[42, 7, 3, 1]
[1, 3, 7, 42]
true
true
1
null
[7, 3]
[42, 7, 3, 1, 100]
[42, 3, 1]
true
0:42 1:7 2:3 3:1Sets und Maps
fun main() {
val s = mutableSetOf(3, 1, 3, 2)
s.add(2); s.add(9)
println("$s ${s.size} ${5 in s}")
println(setOf(1, 2, 3) intersect setOf(2, 3, 4))
println(setOf(1, 2, 3) union setOf(2, 3, 4))
println(setOf(1, 2, 3) subtract setOf(2))
val m = mutableMapOf("a" to 1, "b" to 2)
m["c"] = 3
m.put("a", 10)
println(m)
println("${m["a"]} ${m["x"]} ${m.getOrDefault("x", 0)} ${m.getOrElse("y") { -1 }}")
println("${m.keys} ${m.values} ${m.size} ${m.containsKey("b")}")
m.remove("b")
for ((k, v) in m) print("$k=$v ")
println()
println(m.mapValues { it.value * 2 })
println(m.filter { it.value > 5 })
println(m.toList())
val zaehler = mutableMapOf<Char, Int>()
for (c in "mississippi") zaehler[c] = (zaehler[c] ?: 0) + 1
println(zaehler)
}Ausgabe:
[3, 1, 2, 9] 4 false
[2, 3]
[1, 2, 3, 4]
[1, 3]
{a=10, b=2, c=3}
10 null 0 -1
[a, b, c] [10, 2, 3] 3 true
a=10 c=3
{a=20, c=6}
{a=10}
[(a, 10), (c, 3)]
{m=1, i=4, s=4, p=2}map, filter, reduce und mehr
Hier zeigt sich Kotlins Stärke: Collections lassen sich mit wenigen Funktionen umformen.
data class Mensch(val name: String, val alter: Int, val stadt: String)
fun main() {
val z = listOf(1, 2, 3, 4, 5, 6)
println(z.map { it * it })
println(z.filter { it % 2 == 0 })
println(z.reduce { a, b -> a + b })
println(z.fold(100) { a, b -> a - b })
println("${z.sum()} ${z.count { it > 3 }} ${z.any { it > 5 }} ${z.all { it > 0 }} ${z.none { it > 9 }}")
println(z.take(2))
println(z.drop(4))
println(z.takeWhile { it < 4 })
println(z.partition { it > 3 })
println(z.chunked(4))
println(z.windowed(3))
println(z.zip(listOf("a", "b", "c")))
println(z.find { it > 3 })
println(z.firstOrNull { it > 10 })
println(listOf(listOf(1, 2), listOf(3)).flatten())
println(listOf("ab", "cd").flatMap { it.toList() })
println(listOf(1, 2, 2, 3, 3, 3).distinct())
println(listOf("x", "y").joinToString(prefix = "[", postfix = "]", separator = "; "))
val leute = listOf(Mensch("Mia", 17, "Berlin"), Mensch("Tom", 25, "Hamburg"),
Mensch("Zoe", 31, "Berlin"), Mensch("Ben", 25, "Köln"))
println(leute.groupBy { it.stadt }.mapValues { e -> e.value.map { it.name } })
println(leute.sortedBy { it.alter }.map { it.name })
println(leute.sortedWith(compareBy({ -it.alter }, { it.name })).map { it.name })
println(leute.maxBy { it.alter }?.name)
println(leute.map { it.alter }.average())
println(leute.associateBy { it.name }.keys)
println(leute.associate { it.name to it.alter })
println(leute.groupingBy { it.stadt }.eachCount())
}Ausgabe:
[1, 4, 9, 16, 25, 36]
[2, 4, 6]
21
79
21 3 true true true
[1, 2]
[5, 6]
[1, 2, 3]
([4, 5, 6], [1, 2, 3])
[[1, 2, 3, 4], [5, 6]]
[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
[(1, a), (2, b), (3, c)]
4
null
[1, 2, 3]
[a, b, c, d]
[1, 2, 3]
[x; y]
{Berlin=[Mia, Zoe], Hamburg=[Tom], Köln=[Ben]}
[Mia, Tom, Ben, Zoe]
[Zoe, Ben, Tom, Mia]
Zoe
24.5
[Mia, Tom, Zoe, Ben]
{Mia=17, Tom=25, Zoe=31, Ben=25}
{Berlin=2, Hamburg=1, Köln=1}Sequenzen: faul statt sofort
Collection-Ketten erzeugen Zwischenlisten. asSequence() verarbeitet Element für Element (lazy), gut für große oder unendliche Folgen:
fun main() {
val ergebnis = (1..1_000_000).asSequence()
.filter { it % 3 == 0 }
.map { it * 2 }
.take(5)
.toList()
println(ergebnis)
val fib = generateSequence(Pair(0, 1)) { Pair(it.second, it.first + it.second) }.map { it.first }
println(fib.take(10).toList())
val s = sequence {
yield(1)
yield(2)
yieldAll(listOf(3, 4))
}
println(s.toList())
}Ausgabe:
[6, 12, 18, 24, 30]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
[1, 2, 3, 4]Arrays
fun main() {
val a = intArrayOf(5, 2, 8)
a[0] = 1
a.sort()
println(a.joinToString())
val b = Array(3) { i -> i * i }
println(b.toList())
println(arrayOf("x", "y").size)
println(a.sum())
}Ausgabe:
1, 2, 8
[0, 1, 4]
2
11Merke
listOf/setOf/mapOf(fest) undmutableListOf… (veränderbar)- Maps:
m["k"],to,for ((k, v) in m) map,filter,reduce,fold,groupBy,sortedBy,zip,flatMap,associateasSequence()für lazy Verarbeitung- Arrays (
IntArray,Array<T>) für feste Größe und Leistung
Übungsaufgabe
Zähle mit groupingBy die Wörter eines Satzes und gib die häufigsten zuerst aus.
Quiz zur Selbstkontrolle
Wie viele Elemente hat setOf(1, 2, 2, 3)?
- 3 (richtig)
- 4
- 2
- 1
Was macht partition?
- Teilt eine Collection anhand einer Bedingung in zwei Listen (richtig)
- Sortiert
- Löscht Elemente
- Verbindet Listen
Wozu dient asSequence()?
- Lazy Verarbeitung ohne Zwischenlisten (richtig)
- Sortieren
- Kopieren
- Parallelisieren
Weiter im Kurs
Zurück: Null-Sicherheit
Weiter: Klassen und Objekte
Alle Kapitel: Kotlin im Überblick