Generische Funktionen
Teil des Abschnitts Objektorientierte Programmierung der Kotlin-Journey von Coddy. Lektion 37 von 57.
Eine generische Funktion funktioniert mit jedem Typ. Ihr Typparameter, der vor dem Funktionsnamen in spitzen Klammern geschrieben wird, steht für den Typ, den der Aufrufer verwendet. T ist die übliche Bezeichnung:
fun <T> firstOr(list: List<T>, default: T): T = if (list.isEmpty()) default else list[0]Innerhalb von main:
println(firstOr(listOf(3, 5), 0) + 1)
println(firstOr(listOf<String>(), "none").uppercase())Ausgabe:
4
NONEKotlin leitet das Typargument aus den Argumenten ab. Wenn es nichts gibt, aus dem es abgeleitet werden kann, schreibst du es selbst, wie oben bei listOf<String>():
fun <T> repeatItem(item: T, times: Int): List<T> = List(times) { item }Innerhalb von main:
println(repeatItem("ab", 3))
println(repeatItem(7, 2))
val empty = repeatItem<Double>(1.5, 0)
println(empty)Ausgabe:
[ab, ab, ab]
[7, 7]
[]Eine Funktion kann mehrere Typparameter haben, und ein Funktionstyp-Parameter kann sie verwenden. So funktionieren Bibliotheksfunktionen wie map für jeden Element- und Ergebnistyp:
fun <A, B> transform(items: List<A>, f: (A) -> B): List<B> {
val out = mutableListOf<B>()
for (item in items) out.add(f(item))
return out
}
fun <K, V> invert(map: Map<K, V>): Map<V, K> = map.entries.associate { (k, v) -> v to k }Innerhalb von main:
println(transform(listOf("kiwi", "fig")) { it.length })
println(invert(mapOf("a" to 1, "b" to 2)))Ausgabe:
[4, 3]
{1=a, 2=b}Ein Typparameter behält den Typ des Aufrufers bei. firstOr(listOf(3, 5), 0) gibt ein Int zurück, daher wird + 1 kompiliert. Eine für List<Any> geschriebene Version würde ebenfalls jede Liste akzeptieren, aber sie würde Any zurückgeben und bei jedem Aufruf eine Typumwandlung erzwingen:
fun firstAny(list: List<Any>, default: Any): Any = if (list.isEmpty()) default else list[0]
// firstAny(listOf(3, 5), 0) + 1 // Fehler: Any hat kein plus
(firstAny(listOf(3, 5), 0) as Int) + 1 // kompiliert, benötigt aber einen Cast
firstOr(listOf(3, 5), 0) + 1 // generisch: das Ergebnis ist ein IntAufgabe
EinfachSchreibe zwei generische Funktionen, die mit Listen beliebigen Typs arbeiten. countWhere(items, predicate) gibt zurück, wie viele Elemente das Prädikat erfüllen, eine Funktion (T) -> Boolean. mostCommon(items) gibt das Element zurück, das am häufigsten vorkommt (bei gleicher Anzahl dasjenige, das zuerst in der Liste erscheint), oder null für eine leere Liste.
Der bereitgestellte Code liest eine Zeile mit Wörtern und eine Zeile mit Zahlen ein und gibt die Anzahl der Wörter mit mehr als 3 Buchstaben, das häufigste Wort, die Anzahl der geraden Zahlen, die häufigste Zahl sowie nothing: null für eine leere Liste aus.
Dein Code gehört in ListTools.kt. Main.kt enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
fun main() {
// Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
val input = generateSequence(::readLine).toList()
val words = input[0].split(" ")
val numbers = input[1].split(" ").map { it.toInt() }
println("long words: ${countWhere(words) { it.length > 3 }}")
println("most common word: ${mostCommon(words)}")
println("even numbers: ${countWhere(numbers) { it % 2 == 0 }}")
println("most common number: ${mostCommon(numbers)}")
println("nothing: ${mostCommon(listOf<String>())}")
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenPrimärkonstruktoreninit-Blöcke und ValidierungSekundärkonstruktorenRückblick – Bibliotheksausweis4Vererbung
Offene Klassen und UnterklassenÜberschreiben von Membernsuper und KonstruktorenAbstrakte KlassenRückblick – Mitarbeiterverzeichnis2Eigenschaften und Kapselung
Benutzerdefinierte ZugriffsmethodenSichtbarkeitsmodifikatorenPrivate Setterlazy und lateinitWiederholung – Bankkonto5Schnittstellen
Schnittstellen deklarierenStandardmethodenMehrere SchnittstellenSchnittstellen als TypenRückblick – Zahlungsmethoden8Generics
Generische FunktionenGenerische KlassenTypbeschränkungenVarianz mit in und outRückblick – Prioritätswarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Kotlin-Playground