目录
- [Lambda 基础概念](#Lambda 基础概念)
- [Lambda 语法详解](#Lambda 语法详解)
- [与 Java 对比](#与 Java 对比)
- [Lambda 的使用场景](#Lambda 的使用场景)
- 高级特性
- 实际应用示例
1. Lambda 基础概念
什么是 Lambda?
Lambda 表达式是一个匿名函数,可以作为值传递、存储和调用。
核心特点:
- 没有函数名
- 可以作为参数传递
- 可以作为返回值
- 可以赋值给变量
2. Lambda 语法详解
2.1 基本语法
kotlin
// 完整语法
{ 参数列表 -> 函数体 }
// 示例
val sum = { a: Int, b: Int -> a + b }
2.2 Lambda 的类型
Lambda 的类型是函数类型 ,格式:(参数类型) -> 返回类型
kotlin
// 无参数,无返回值
val action: () -> Unit = { println("Hello") }
// 一个参数,返回 Int
val length: (String) -> Int = { it.length }
// 两个参数,返回 String
val combine: (String, String) -> String = { a, b -> "$a$b" }
// 参数为函数类型(高阶函数)
val higherOrder: ((Int) -> Int) -> Int = { func -> func(5) }
2.3 Lambda 的简化写法
情况1:参数类型可以推断
kotlin
// 完整写法
val length1: (String) -> Int = { str: String -> str.length }
// 简化写法(类型推断)
val length2: (String) -> Int = { str -> str.length }
情况2:单个参数可以用 it
kotlin
// 完整写法
val length1: (String) -> Int = { str -> str.length }
// 使用 it(最常用)
val length2: (String) -> Int = { it.length }
情况3:最后一个参数是 Lambda,可以移出括号
kotlin
// 标准写法
list.filter({ it > 0 })
// Lambda 移出括号(推荐)
list.filter { it > 0 }
// 多个参数的情况
list.fold(0, { acc, value -> acc + value })
list.fold(0) { acc, value -> acc + value } // 推荐
情况4:Lambda 是唯一参数,可以省略括号
kotlin
// 标准写法
list.forEach({ println(it) })
// 省略括号
list.forEach { println(it) }
3. 与 Java 对比
3.1 基本语法对比
| 特性 | Kotlin | Java 8+ |
|---|---|---|
| 语法 | { x -> x * 2 } |
x -> x * 2 |
| 类型 | (Int) -> Int |
Function<Int, Integer> |
| 单参数简化 | it |
无(必须写参数名) |
| 调用方式 | func(5) |
func.apply(5) |
3.2 实际代码对比
Kotlin:
kotlin
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = numbers.map { it * 2 }
val filtered = numbers.filter { it > 3 }
numbers.forEach { println(it) }
Java:
java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> doubled = numbers.stream()
.map(x -> x * 2)
.collect(Collectors.toList());
List<Integer> filtered = numbers.stream()
.filter(x -> x > 3)
.collect(Collectors.toList());
numbers.forEach(x -> System.out.println(x));
4. Lambda 的使用场景
4.1 作为函数参数(高阶函数)
kotlin
// 定义高阶函数
fun processNumbers(numbers: List<Int>, operation: (Int) -> Int): List<Int> {
return numbers.map(operation)
}
// 使用
val numbers = listOf(1, 2, 3, 4, 5)
val doubled = processNumbers(numbers) { it * 2 }
val squared = processNumbers(numbers) { it * it }
4.2 集合操作
kotlin
val numbers = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
// map: 转换每个元素
val doubled = numbers.map { it * 2 }
// filter: 过滤元素
val evens = numbers.filter { it % 2 == 0 }
// forEach: 遍历执行
numbers.forEach { println(it) }
// find: 查找第一个满足条件的
val firstEven = numbers.find { it % 2 == 0 }
// any: 判断是否有满足条件的
val hasEven = numbers.any { it % 2 == 0 }
// all: 判断是否全部满足条件
val allPositive = numbers.all { it > 0 }
// count: 统计满足条件的数量
val evenCount = numbers.count { it % 2 == 0 }
// fold: 累积操作
val sum = numbers.fold(0) { acc, value -> acc + value }
// reduce: 累积操作(无初始值)
val product = numbers.reduce { acc, value -> acc * value }
4.3 作用域函数(Scope Functions)
Kotlin 提供了 5 个作用域函数,都使用 Lambda:
let
kotlin
// 使用 let 安全调用
val result = nullableString?.let {
it.length // it 是 nullableString
}
// 等价于 Java
// if (nullableString != null) {
// int result = nullableString.length();
// }
run
kotlin
// run 可以访问对象成员
val result = "Hello".run {
length + uppercase().length // this 是 "Hello"
}
with
kotlin
// with 不是扩展函数
val result = with("Hello") {
length + uppercase().length // this 是 "Hello"
}
apply
kotlin
// apply 返回对象本身
val person = Person().apply {
name = "张三"
age = 25
// 返回 this(Person 对象)
}
also
kotlin
// also 返回对象本身,但用 it 访问
val numbers = mutableListOf(1, 2, 3)
numbers.also {
println("列表大小: ${it.size}") // it 是 numbers
}.add(4)
4.4 延迟初始化
kotlin
// lazy 初始化
val expensiveValue: String by lazy {
println("计算中...")
"计算结果"
}
// 第一次访问时才计算
println(expensiveValue) // 输出: 计算中... 计算结果
println(expensiveValue) // 输出: 计算结果(不再计算)
5. 高级特性
5.1 带接收者的 Lambda(Receiver)
kotlin
// 定义带接收者的函数类型
fun buildString(builder: StringBuilder.() -> Unit): String {
val sb = StringBuilder()
sb.builder() // 在 StringBuilder 上下文中执行
return sb.toString()
}
// 使用
val result = buildString {
append("Hello")
append(" ")
append("World")
// this 是 StringBuilder 实例
}
5.2 Lambda 中的 return
kotlin
// 普通 return(从函数返回)
fun findFirst(numbers: List<Int>): Int? {
numbers.forEach {
if (it > 5) {
return null // 从 findFirst 函数返回
}
}
return 0
}
// 标签 return(从 Lambda 返回)
fun findFirstLabeled(numbers: List<Int>): Int? {
numbers.forEach label@{
if (it > 5) {
return@label // 只从 Lambda 返回,继续循环
}
}
return 0
}
// 隐式标签(使用函数名)
fun findFirstImplicit(numbers: List<Int>): Int? {
numbers.forEach {
if (it > 5) {
return@forEach // 从 forEach 的 Lambda 返回
}
}
return 0
}
5.3 Lambda 参数解构
kotlin
// Map 遍历
val map = mapOf("a" to 1, "b" to 2, "c" to 3)
map.forEach { (key, value) ->
println("$key -> $value")
}
// List 中的 Pair
val pairs = listOf(Pair("a", 1), Pair("b", 2))
pairs.forEach { (first, second) ->
println("$first -> $second")
}
5.4 多个 Lambda 参数
kotlin
// 定义
fun process(
onStart: () -> Unit,
onProgress: (Int) -> Unit,
onComplete: (String) -> Unit
) {
onStart()
for (i in 1..10) {
onProgress(i)
}
onComplete("完成")
}
// 使用(最后一个 Lambda 可以移出括号)
process(
onStart = { println("开始") },
onProgress = { println("进度: $it") }
) { result ->
println("结果: $result")
}
6. 实际应用示例
6.1 Android/Compose 中的使用
kotlin
// Button 点击事件
Button(onClick = {
println("按钮被点击")
}) {
Text("点击我")
}
// 列表项点击
LazyColumn {
items(items) { item ->
Card(
onClick = { handleItemClick(item) }
) {
Text(item.name)
}
}
}
// 状态管理
var count by remember { mutableStateOf(0) }
Button(onClick = { count++ }) {
Text("计数: $count")
}
6.2 网络请求回调
kotlin
// 定义回调接口
fun fetchData(
onSuccess: (String) -> Unit,
onError: (Exception) -> Unit
) {
// 模拟网络请求
try {
val data = "数据内容"
onSuccess(data)
} catch (e: Exception) {
onError(e)
}
}
// 使用
fetchData(
onSuccess = { data ->
println("成功: $data")
},
onError = { error ->
println("错误: ${error.message}")
}
)
6.3 自定义 DSL(领域特定语言)
kotlin
// 定义 DSL 构建器
class HTML {
fun body(init: Body.() -> Unit) {
val body = Body()
body.init()
}
}
class Body {
fun div(init: Div.() -> Unit) {
val div = Div()
div.init()
}
}
class Div {
var text: String = ""
}
// 使用 DSL
val html = HTML()
html.body {
div {
text = "Hello World"
}
}
7. 最佳实践
7.1 何时使用 Lambda
✅ 适合使用:
- 简单的单行操作
- 作为高阶函数的参数
- 集合操作
- 回调函数
❌ 不适合使用:
- 复杂的多行逻辑(应该提取为函数)
- 需要多个 return 的复杂逻辑
- 需要命名和复用的逻辑
7.2 性能考虑
kotlin
// ❌ 不好的做法:在循环中创建大量 Lambda
for (i in 1..1000000) {
list.map { it * i } // 每次循环都创建 Lambda
}
// ✅ 好的做法:提取 Lambda
val multiplier = { x: Int -> x * 2 }
for (i in 1..1000000) {
list.map(multiplier)
}
7.3 可读性
kotlin
// ❌ 可读性差:嵌套太深
list.filter { it > 0 }
.map { it * 2 }
.filter { it < 100 }
.forEach { println(it) }
// ✅ 可读性好:提取中间变量
val positiveNumbers = list.filter { it > 0 }
val doubled = positiveNumbers.map { it * 2 }
val filtered = doubled.filter { it < 100 }
filtered.forEach { println(it) }
总结
Kotlin Lambda 的核心优势:
- 语法简洁:比 Java 更直观
- 类型推断:减少样板代码
- 函数式编程:支持高阶函数
- 作用域函数:提供强大的对象操作能力
- DSL 支持:可以创建领域特定语言
作为 Java 开发者,理解 Lambda 是掌握 Kotlin 函数式编程的关键!