Menu
CoddyTech

Fungsi Generik

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Kotlin di Coddy. Pelajaran 37 dari 57.

Fungsi generik bekerja dengan tipe apa pun. Parameter tipe, yang ditulis dalam tanda kurung sudut sebelum nama fungsi, mewakili tipe yang digunakan pemanggil. T adalah nama yang umum:

fun <T> firstOr(list: List<T>, default: T): T = if (list.isEmpty()) default else list[0]

Di dalam main:

println(firstOr(listOf(3, 5), 0) + 1)
println(firstOr(listOf<String>(), "none").uppercase())

Output:

4
NONE

Kotlin menyimpulkan argumen tipe dari argumen-argumennya. Jika tidak ada yang bisa digunakan untuk menyimpulkannya, kamu menulisnya sendiri, seperti pada listOf<String>() di atas:

fun <T> repeatItem(item: T, times: Int): List<T> = List(times) { item }

Di dalam main:

println(repeatItem("ab", 3))
println(repeatItem(7, 2))
val empty = repeatItem<Double>(1.5, 0)
println(empty)

Output:

[ab, ab, ab]
[7, 7]
[]

Sebuah fungsi dapat memiliki beberapa parameter tipe, dan parameter bertipe fungsi dapat menggunakannya. Beginilah fungsi library seperti map bekerja untuk setiap tipe elemen dan hasil:

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 }

Di dalam main:

println(transform(listOf("kiwi", "fig")) { it.length })
println(invert(mapOf("a" to 1, "b" to 2)))

Output:

[4, 3]
{1=a, 2=b}

Parameter tipe mempertahankan tipe pemanggil. firstOr(listOf(3, 5), 0) mengembalikan Int, jadi + 1 bisa dikompilasi. Versi yang ditulis untuk List<Any> juga akan menerima setiap list, tetapi akan mengembalikan Any dan mengharuskan kamu melakukan cast pada setiap pemanggilan:

fun firstAny(list: List<Any>, default: Any): Any = if (list.isEmpty()) default else list[0]
// firstAny(listOf(3, 5), 0) + 1               // error: Any tidak memiliki plus
(firstAny(listOf(3, 5), 0) as Int) + 1         // bisa di-compile, tetapi memerlukan cast
firstOr(listOf(3, 5), 0) + 1                   // generik: hasilnya bertipe Int
challenge icon

Tantangan

Mudah

Tulis dua fungsi generik yang berfungsi untuk list dengan tipe apa pun. countWhere(items, predicate) mengembalikan jumlah elemen yang memenuhi predicate, yaitu fungsi (T) -> Boolean. mostCommon(items) mengembalikan elemen yang paling sering muncul (elemen yang muncul pertama dalam list jika jumlah kemunculannya sama), atau null untuk list kosong.

Kode yang disediakan membaca satu baris berisi kata-kata dan satu baris berisi angka, lalu mencetak jumlah kata yang panjangnya lebih dari 3 huruf, kata yang paling sering muncul, jumlah angka genap, angka yang paling sering muncul, dan nothing: null untuk list kosong.

Tulis kodemu di ListTools.kt. Main.kt berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

fun main() {
    // Kode input/output yang disediakan: biarkan apa adanya
    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>())}")
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Playground Kotlin