🚀 Higher-Order Functions
🎯 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
Phần tiêu đề “💡 Khái niệm”Higher-Order Function là hàm có một trong hai đặc điểm:
- Nhận một hàm làm tham số
- 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
Phần tiêu đề “📝 Function Types”Cú pháp
Phần tiêu đề “Cú pháp”(ParameterTypes) -> ReturnTypeVí dụ
Phần tiêu đề “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
Phần tiêu đề “⭐ Định nghĩa HOF”Nhận function làm tham số
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “🔗 Built-in HOF cho Collections”val numbers = listOf(1, 2, 3, 4, 5)val squared = numbers.map { it * it }println(squared) // [1, 4, 9, 16, 25]filter
Phần tiêu đề “filter”val numbers = listOf(1, 2, 3, 4, 5, 6)val even = numbers.filter { it % 2 == 0 }println(even) // [2, 4, 6]reduce / fold
Phần tiêu đề “reduce / fold”val numbers = listOf(1, 2, 3, 4, 5)val sum = numbers.reduce { acc, n -> acc + n } // 15val product = numbers.fold(1) { acc, n -> acc * n } // 120find / first / last
Phần tiêu đề “find / first / last”val numbers = listOf(1, 2, 3, 4, 5)val firstEven = numbers.find { it % 2 == 0 } // 2val firstOrNull = numbers.firstOrNull { it > 10 } // nullany / all / none
Phần tiêu đề “any / all / none”val numbers = listOf(1, 2, 3, 4, 5)println(numbers.any { it > 3 }) // true - có ít nhất 1println(numbers.all { it > 0 }) // true - tất cảprintln(numbers.none { it < 0 }) // true - không cógroupBy / partition
Phần tiêu đề “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
Phần tiêu đề “🔄 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
Phần tiêu đề “🛠️ 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
Phần tiêu đề “📱 Trong Android”// Custom view extensioninline fun View.doOnClick(crossinline action: () -> Unit) { setOnClickListener { action() }}
// Usagebutton.doOnClick { navigateToNext()}
// LiveData transformationval users: LiveData<List<User>> = repository.getUsers()val activeUsers: LiveData<List<User>> = users.map { list -> list.filter { it.isActive }}
// Network call wrappersuspend fun <T> safeApiCall( apiCall: suspend () -> T): Result<T> { return try { Result.success(apiCall()) } catch (e: Exception) { Result.failure(e) }}⚠️ Lưu ý quan trọng
Phần tiêu đề “⚠️ Lưu ý quan trọng”✅ Checklist - Tự kiểm tra
Phần tiêu đề “✅ 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