Lambda表达式
Lambda表达式是一种简洁的方式来定义匿名函数。Kotlin的Lambda表达式非常灵活,常用于函数式编程、集合操作、高阶函数等场景。
无参数的Lambda表达式
格式 :{函数体}
调用:{函数体}()
kotlin
val greet = { println("Hello, Kotlin!") }
greet() // 输出: Hello, Kotlin!
有参数的Lambda表达式
格式 :{参数名:参数类型,参数名:参数类型... -> 函数体}
调用:{参数名:参数类型,参数名:参数类型... -> 函数体}(参数1,参数2...)
kotlin
val sum = { a: Int, b: Int -> a + b }
println(sum(2, 3)) // 输出: 5
Lambda返回值
- 方法返回值由方法体最后一句语句决定。
kotlin
val str = {
println("Lambda返回值")
"今天天气真好"
}()
println("$str")
Lambda 表达式作为函数参数
- Lambda 表达式可以作为函数的参数传递,这是函数式编程的重要特性之一。这种特性使得代码更加简洁、灵活。
基本用法
将 Lambda 作为最后一个参数
当 Lambda 表达式是函数的最后一个参数时,可以将其放在括号外面:
kotlin
fun processNumbers(numbers: List<Int>, action: (Int) -> Unit) {
for (number in numbers) {
action(number)
}
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5)
// 常规调用方式
processNumbers(numbers, { number -> println(number) })
// Lambda 在括号外的简化写法
processNumbers(numbers) { number -> println(number) }
// 使用 it 简化单参数 Lambda
processNumbers(numbers) { println(it) }
}
Lambda 作为唯一参数
如果函数只有一个 Lambda 参数,可以完全省略括号:
kotlin
fun execute(action: () -> Unit) {
action()
}
fun main() {
execute { println("Hello from Lambda!") }
}
高阶函数示例
Lambda 作为参数的高阶函数示例:
fun List.filterOnCondition(condition: (Int) -> Boolean): List {
val result = mutableListOf()
for (item in this) {
if (condition(item)) {
result.add(item)
}
}
return result
}
fun main() {
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// 过滤偶数
val evens = numbers.filterOnCondition { it % 2 == 0 }
println(evens) // [2, 4, 6, 8, 10]
// 过滤大于5的数
val greaterThan5 = numbers.filterOnCondition { it > 5 }
println(greaterThan5) // [6, 7, 8, 9, 10]
}
Lambda 表达式函数参数用法
基本用法
返回 Lambda 表达式的基本语法
kotlin
fun createGreeter(greeting: String): (String) -> String {
return { name -> "$greeting, $name!" }
}
fun main() {
val englishGreeter = createGreeter("Hello")
println(englishGreeter("Alice")) // 输出: Hello, Alice!
val spanishGreeter = createGreeter("Hola")
println(spanishGreeter("Bob")) // 输出: Hola, Bob!
}
直接返回 Lambda 表达式
可以省略返回类型声明,让编译器推断:
kotlin
fun createMultiplier(factor: Int) = { number: Int -> number * factor }
fun main() {
val double = createMultiplier(2)
println(double(5)) // 输出: 10
val triple = createMultiplier(3)
println(triple(5)) // 输出: 15
}
高级用法
返回带接收者的 Lambda
kotlin
fun createStringBuilderAction(): StringBuilder.() -> Unit {
return {
append("Hello, ")
append("World!")
}
}
fun main() {
val action = createStringBuilderAction()
val sb = StringBuilder()
sb.action()
println(sb.toString()) // 输出: Hello, World!
}
返回多个操作的组合 Lambda
kotlin
fun createOperation(operator: String): (Int, Int) -> Int {
return when (operator) {
"add" -> { a, b -> a + b }
"subtract" -> { a, b -> a - b }
"multiply" -> { a, b -> a * b }
else -> throw IllegalArgumentException("Unknown operator")
}
}
fun main() {
val add = createOperation("add")
println(add(5, 3)) // 输出: 8
val multiply = createOperation("multiply")
println(multiply(5, 3)) // 输出: 15
}
标准库中的高阶函数
集合基本查找函数
find / firstOrNull
- 返回第一个满足条件的元素,找不到则返回 null
- 两者功能完全相同,firstOrNull 语义更明确
kotlin
Iterable<T>.find(predicate: (T) -> Boolean): T?
Iterable<T>.firstOrNull(predicate: (T) -> Boolean): T?
kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8)
val firstEven = numbers.find { it % 2 == 0 } // 2
val firstOver10 = numbers.firstOrNull { it > 10 } // null
first
- 返回第一个满足条件的元素
- 找不到会抛出 NoSuchElementException
kotlin
val firstOdd = numbers.first { it % 2 != 0 } // 1
// numbers.first { it > 10 } // 抛出 NoSuchElementException
last / lastOrNull
- 与 first 系列类似,但是从集合末尾开始查找
kotlin
val lastEven = numbers.last { it % 2 == 0 } // 8
val lastUnder5 = numbers.lastOrNull { it < 5 } // 4
存在性检查函数
any
- 检查集合中是否存在至少一个满足条件的元素
kotlin
val hasEven = numbers.any { it % 2 == 0 } // true
val hasNegative = numbers.any { it < 0 } // false
none
- 检查集合中是否没有任何元素满足条件
kotlin
val noZeros = numbers.none { it == 0 } // true
val noEvens = numbers.none { it % 2 == 0 } // false
all
- 检查集合中所有元素是否都满足条件
kotlin
val allPositive = numbers.all { it > 0 } // true
val allEven = numbers.all { it % 2 == 0 } // false
索引查找函数
indexOfFirst
- 返回第一个满足条件的元素的索引,找不到返回 -1
kotlin
val firstEvenIndex = numbers.indexOfFirst { it % 2 == 0 } // 1
indexOfLast
- 返回最后一个满足条件的元素的索引,找不到返回 -1
kotlin
val lastEvenIndex = numbers.indexOfLast { it % 2 == 0 } // 7
特殊查找函数
single
- 查找唯一满足条件的元素
- single 如果没有或找到多个会抛出异常
- singleOrNull 没有返回 null,多个也返回 null
kotlin
val singleDigit = listOf(1, 2, 3).single { it == 2 } // 2
// listOf(1, 2, 3).single { it > 1 } // 抛出 IllegalArgumentException
val unique = listOf(1, 2, 3).singleOrNull { it == 4 } // null
takeWhile
- 从集合的第一个元素开始,顺序取出满足条件的元素,直到遇到第一个不满足条件的元素为止。
- 返回的是新集合(List)
- 原集合不会被修改
kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val result = numbers.takeWhile { it < 5 }
println(result) // 输出: [1, 2, 3, 4]
filter
- 筛选出集合中所有满足条件的元素,与 takeWhile 不同,它会检查所有元素
- 返回满足条件的所有元素
- 原集合不会被修改
kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evenNumbers = numbers.filter { it % 2 == 0 }
println(evenNumbers) // 输出: [2, 4, 6, 8, 10]
- filterNot:筛选出不满足条件的元素
- filterIndexed:可以使用索引进行筛选
- filterIsInstance:按类型筛选
kotlin
val mixedList = listOf(1, "two", 3, "four", 5.0)
val strings = mixedList.filterIsInstance<String>()
println(strings) // 输出: [two, four]
count
- 统计集合中满足条件的元素数量。
- 返回的是满足条件的元素数量(Int)
- 比先 filter 再 size 更高效
- 无参数时返回集合大小
kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
val evenCount = numbers.count { it % 2 == 0 }
println(evenCount) // 输出: 5
standard库中的函数
repeat
- 简单的循环函数,用于重复执行某个操作指定的次数
kotlin
/*
* @param times 重复次数
*
*/
repeat(times: Int, action: (Int) -> Unit)
kotlin
repeat(3) {
println("Hello") // 会打印3次"Hello"
}
- 第一个参数是重复次数(Int)
- 第二个参数是 Lambda 表达式(动作)
- 在 Lambda 中可以通过 it 访问当前迭代的索引(从0开始)
kotlin
repeat(3) { index ->
println("Iteration $index") // 打印 Iteration 0, Iteration 1, Iteration 2
}
run
- 有两种形式:扩展函数和非扩展函数。
- 扩展函数形式
kotlin
T.run(block: T.() -> R): R
kotlin
val result = "Hello".run {
println(this) // "Hello" (this指向接收者)
length // 返回值是Lambda的最后一行
}
println(result) // 5
- 非扩展函数形式
kotlin
run(block: () -> R): R
kotlin
val result = run {
val x = 5
val y = 3
x + y // 返回值
}
println(result) // 8
let
- 扩展函数,主要用于在非空对象上执行操作。
kotlin
val name: String? = "Kotlin"
name?.let {
println(it) // "Kotlin" (it指向接收者)
println(it.length) // 6
}
- 常用于空安全检查
- 参数是对象本身(用 it 引用)
- 返回 Lambda 的最后一行结果
apply
- 用于配置对象的属性,返回对象本身
kotlin
val person = Person().apply {
name = "Alice" // this.name = "Alice"
age = 25 // this.age = 25
}
- 在 Lambda 中,this 指向接收者对象
- 返回接收者对象本身
- 常用于对象初始化
with
- 非扩展函数,允许在对象的上下文中执行代码块
kotlin
val person = Person("Bob", 30)
val result = with(person) {
println(name) // 可以直接访问属性
println(age)
"Name: $name, Age: $age" // 返回值
}
- 第一个参数是接收者对象
- 在 Lambda 中,this 指向接收者对象
- 返回 Lambda 的最后一行结果