Kotlin 高级函数与 Lambda 结合运用
Kotlin 中高级函数与 Lambda 表达式的结合使用是函数式编程的核心特性,可以写出简洁、表达力强的代码。让我详细介绍这些概念及其实际应用。
1. 基础 Lambda 表达式
// 基本 Lambda 语法
val sum = { x: Int, y: Int -> x + y }
// 调用 Lambda
println(sum(5, 3)) // 输出: 8
// 作为函数参数
val numbers = listOf(1, 2, 3, 4, 5)
numbers.forEach { println(it) }
// 单参数时,it 关键字
val doubled = numbers.map { it * 2 }
2. 函数类型与高阶函数
// 函数类型声明
typealias Operation = (Int, Int) -> Int
// 高阶函数:接收函数作为参数
fun calculate(a: Int, b: Int, operation: Operation): Int {
return operation(a, b)
}
// 高阶函数:返回函数
fun getMultiplier(factor: Int): (Int) -> Int {
return { number -> number * factor }
}
// 使用示例
val addition: Operation = { x, y -> x + y }
val result = calculate(10, 5, addition) // 15
val double = getMultiplier(2)
println(double(5)) // 10
3. 常用高阶函数实践
集合操作
data class Person(val name: String, val age: Int)
val people = listOf(
Person("Alice", 29),
Person("Bob", 31),
Person("Charlie", 25),
Person("Diana", 28)
)
// filter 与 map 结合
val namesOfAdults = people
.filter { it.age >= 18 }
.map { it.name }
.sorted()
// groupBy
val groupedByAge = people.groupBy { it.age / 10 * 10 }
// 结果: {20=[...], 30=[...]}
// fold 与 reduce
val totalAge = people.fold(0) { acc, person -> acc + person.age }
val oldest = people.reduce { p1, p2 -> if (p1.age > p2.age) p1 else p2 }
// flatMap
val allHobbies = people.flatMap { person ->
getHobbies(person) // 假设返回 List<String>
}
作用域函数
data class User(var name: String, var age: Int, var email: String?)
// let - 安全调用与转换
val userEmailLength = user?.let {
it.email?.length ?: 0
}
// apply - 对象配置
val user = User("", 0, null).apply {
name = "Alice"
age = 30
email = "alice@example.com"
}
// run - 执行代码块并返回结果
val userInfo = user.run {
"Name: $name, Age: $age"
}
// with - 非扩展函数版本
with(user) {
println("User: $name")
// 多个操作
}
// also - 附加操作
val processedUser = user.also {
println("Processing user: ${it.name}")
// 可以修改 it
}.copy(age = user.age + 1)
4. 自定义高阶函数
带接收者的 Lambda (DSL 构建)
// 定义 HTML DSL
class Html {
private val children = mutableListOf<Any>()
fun body(init: Body.() -> Unit) {
val body = Body().apply(init)
children.add(body)
}
override fun toString() = children.joinToString("\n")
}
class Body {
private val elements = mutableListOf<String>()
fun h1(text: String) {
elements.add("<h1>$text</h1>")
}
fun p(text: String) {
elements.add("<p>$text</p>")
}
override fun toString() = elements.joinToString("\n")
}
// 使用 DSL
val html = Html().apply {
body {
h1("Welcome")
p("This is a paragraph.")
}
}
日志记录高阶函数
fun <T> withLogging(operationName: String, block: () -> T): T {
println("Starting $operationName")
val startTime = System.currentTimeMillis()
val result = try {
block()
} catch (e: Exception) {
println("Error in $operationName: ${e.message}")
throw e
}
val endTime = System.currentTimeMillis()
println("Finished $operationName in ${endTime - startTime}ms")
return result
}
// 使用
val data = withLogging("data processing") {
// 复杂的数据处理
processLargeDataset()
}
5. Lambda 与 Receiver 的进阶用法
// 创建配置构建器
class DatabaseConfig {
var url: String = ""
var username: String = ""
var password: String = ""
var poolSize: Int = 10
fun build(): String = "jdbc:$url?user=$username&password=$password&poolSize=$poolSize"
}
fun database(block: DatabaseConfig.() -> Unit): String {
val config = DatabaseConfig().apply(block)
return config.build()
}
// 使用构建器
val connectionString = database {
url = "mysql://localhost:3306/mydb"
username = "admin"
password = "secret"
poolSize = 20
}
6. 函数组合与管道
// 函数组合
infix fun <A, B, C> ((B) -> C).compose(g: (A) -> B): (A) -> C = { x -> this(g(x)) }
infix fun <A, B, C> ((A) -> B).andThen(f: (B) -> C): (A) -> C = { x -> f(this(x)) }
// 使用函数组合
val add5 = { x: Int -> x + 5 }
val multiplyBy2 = { x: Int -> x * 2 }
val square = { x: Int -> x * x }
val composed = add5 andThen multiplyBy2 andThen square
println(composed(3)) // ((3+5)*2)^2 = 256
// 管道操作
fun <T, R> T.pipe(vararg functions: (T) -> R): R {
var result: Any = this
for (function in functions) {
result = function(result as T)
}
return result as R
}
val result = 10.pipe(
{ it * 2 },
{ it + 5 },
{ it.toString() }
) // "25"
7. 实际应用示例
验证器构建器
class Validator<T> {
private val validations = mutableListOf<(T) -> Boolean>()
fun addValidation(message: String, predicate: (T) -> Boolean) {
validations.add(predicate)
}
fun validate(value: T): List<String> {
return validations.mapNotNull { validation ->
if (!validation(value)) "Validation failed" else null
}
}
}
fun <T> buildValidator(block: Validator<T>.() -> Unit): Validator<T> {
return Validator<T>().apply(block)
}
// 使用
val userValidator = buildValidator<User> {
addValidation("Name must not be empty") { it.name.isNotBlank() }
addValidation("Age must be positive") { it.age > 0 }
addValidation("Email must be valid") { it.email.contains("@") }
}
重试机制
suspend fun <T> withRetry(
maxAttempts: Int = 3,
initialDelay: Long = 100,
maxDelay: Long = 1000,
block: suspend () -> T
): T {
var currentDelay = initialDelay
repeat(maxAttempts - 1) { attempt ->
try {
return block()
} catch (e: Exception) {
println("Attempt ${attempt + 1} failed: ${e.message}")
delay(currentDelay)
currentDelay = (currentDelay * 2).coerceAtMost(maxDelay)
}
}
return block() // 最后一次尝试
}
8. 性能注意事项
- 内联函数:使用
inline关键字避免 Lambda 开销
inline fun <T> measureTime(block: () -> T): T {
val start = System.currentTimeMillis()
val result = block()
val end = System.currentTimeMillis()
println("Execution time: ${end - start}ms")
return result
}
- 避免重复创建 Lambda:在循环外定义 Lambda
// 避免
repeat(1000) {
list.filter { it > 5 }.forEach { println(it) }
}
// 推荐
val filterPredicate = { it: Int -> it > 5 }
val action = { it: Int -> println(it) }
repeat(1000) {
list.filter(filterPredicate).forEach(action)
}
总结
Kotlin 的高级函数和 Lambda 表达式结合使用可以:
- 提高代码表达力:使代码更简洁、意图更明确
- 促进函数组合:通过函数组合构建复杂行为
- 支持 DSL 创建:构建领域特定语言
- 增强代码复用:通过高阶函数抽象通用模式
- 简化异步编程:配合协程使用
掌握这些技巧可以帮助你写出更优雅、可维护的 Kotlin 代码。