Skip to Content
Kotlin📘 Ngôn ngữ Kotlin🚀 Higher-Order Functions

Higher-Order Functions trong Kotlin

🎯 Mục tiêu: Hiểu Higher-Order Functions (HOF) - hàm nhận hàm làm tham số hoặc trả về hàm.


💡 Khái niệm

Higher-Order Function là hàm có một trong hai đặc điểm:

  1. Nhận một hàm làm tham số
  2. Trả về một hàm
// HOF nhận function làm tham số fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int { return operation(a, b) } fun main() { val sum = calculate(5, 3) { a, b -> a + b } println(sum) // 8 }

📝 Function Types

Cú pháp

(ParameterTypes) -> ReturnType

Ví dụ

val sum: (Int, Int) -> Int = { a, b -> a + b } val greet: (String) -> Unit = { println("Hello, $it") } val isEven: (Int) -> Boolean = { it % 2 == 0 } val noParams: () -> String = { "Hello!" }

⭐ Định nghĩa HOF

Nhận function làm tham số

fun repeat(times: Int, action: (Int) -> Unit) { for (i in 0 until times) { action(i) } } fun main() { repeat(3) { index -> println("Iteration $index") } }

Trả về function

fun createMultiplier(factor: Int): (Int) -> Int { return { number -> number * factor } } fun main() { val double = createMultiplier(2) val triple = createMultiplier(3) println(double(5)) // 10 println(triple(5)) // 15 }

🔗 Built-in HOF cho Collections

map

val numbers = listOf(1, 2, 3, 4, 5) val squared = numbers.map { it * it } println(squared) // [1, 4, 9, 16, 25]

filter

val numbers = listOf(1, 2, 3, 4, 5, 6) val even = numbers.filter { it % 2 == 0 } println(even) // [2, 4, 6]

reduce / fold

val numbers = listOf(1, 2, 3, 4, 5) val sum = numbers.reduce { acc, n -> acc + n } // 15 val product = numbers.fold(1) { acc, n -> acc * n } // 120

find / first / last

val numbers = listOf(1, 2, 3, 4, 5) val firstEven = numbers.find { it % 2 == 0 } // 2 val firstOrNull = numbers.firstOrNull { it > 10 } // null

any / all / none

val numbers = listOf(1, 2, 3, 4, 5) println(numbers.any { it > 3 }) // true - có ít nhất 1 println(numbers.all { it > 0 }) // true - tất cả println(numbers.none { it < 0 }) // true - không có

groupBy / partition

val numbers = listOf(1, 2, 3, 4, 5, 6) val grouped = numbers.groupBy { if (it % 2 == 0) "even" else "odd" } println(grouped) // {odd=[1, 3, 5], even=[2, 4, 6]} val (even, odd) = numbers.partition { it % 2 == 0 } println(even) // [2, 4, 6] println(odd) // [1, 3, 5]

🔄 Chaining HOFs

data class User(val name: String, val age: Int, val city: String) val users = listOf( User("Alice", 25, "Hanoi"), User("Bob", 30, "HCMC"), User("Charlie", 20, "Hanoi"), User("David", 35, "Danang") ) val result = users .filter { it.age >= 25 } .sortedBy { it.name } .map { "${it.name} (${it.city})" } .joinToString(", ") println(result) // Alice (Hanoi), Bob (HCMC), David (Danang)

🛠️ Thực hành

Bài tập 1: Tạo custom HOF

fun main() { // TODO: Viết hàm doIf(condition, action) // thực thi action nếu condition đúng }

Lời giải:

inline fun doIf(condition: Boolean, action: () -> Unit) { if (condition) action() } fun main() { val age = 20 doIf(age >= 18) { println("Đủ tuổi") } doIf(age < 18) { println("Chưa đủ tuổi") // Không in } }

Bài tập 2: Retry mechanism

fun main() { // TODO: Viết hàm retry(times, action) // thử lại action nếu throw exception }

Lời giải:

inline fun <T> retry(times: Int, action: () -> T): T? { var lastException: Exception? = null repeat(times) { attempt -> try { return action() } catch (e: Exception) { lastException = e println("Attempt ${attempt + 1} failed: ${e.message}") } } return null } fun main() { var callCount = 0 val result = retry(3) { callCount++ if (callCount < 3) throw Exception("Failed") "Success!" } println(result) // Success! (sau 2 lần thất bại) }

Bài tập 3: Pipeline function

fun main() { // TODO: Tạo pipeline xử lý string }

Lời giải:

fun pipeline( input: String, vararg transforms: (String) -> String ): String { return transforms.fold(input) { acc, transform -> transform(acc) } } fun main() { val result = pipeline( " hello world ", { it.trim() }, { it.uppercase() }, { it.replace(" ", "_") } ) println(result) // HELLO_WORLD }

📱 Trong Android

// Custom view extension inline fun View.doOnClick(crossinline action: () -> Unit) { setOnClickListener { action() } } // Usage button.doOnClick { navigateToNext() } // LiveData transformation val users: LiveData<List<User>> = repository.getUsers() val activeUsers: LiveData<List<User>> = users.map { list -> list.filter { it.isActive } } // Network call wrapper suspend fun <T> safeApiCall( apiCall: suspend () -> T ): Result<T> { return try { Result.success(apiCall()) } catch (e: Exception) { Result.failure(e) } }

⚠️ Lưu ý quan trọng

[!TIP] Dùng inline để tối ưu performance:

// Không inline - tạo object mới cho mỗi lambda fun doSomething(action: () -> Unit) { action() } // Inline - không tạo object, copy code trực tiếp inline fun doSomething(action: () -> Unit) { action() }

✅ Checklist - Tự kiểm tra

Sau bài học này, bạn có thể:

  • Hiểu function types: (Params) -> Return
  • Định nghĩa HOF nhận function làm tham số
  • Định nghĩa HOF trả về function
  • Sử dụng thành thạo map, filter, reduce, fold
  • Chain nhiều HOF lại với nhau
  • Hiểu khi nào dùng inline

Tiếp theo: Scope Functions

Last updated on