Kotlin基础知识学习(五)

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 的最后一行结果
相关推荐
张张张31226 分钟前
4.1学习总结 拼图小游戏+集合进阶
java·学习
RadNIkMan1 小时前
Python学习(二)操作列表
网络·python·学习
yanxy5121 小时前
【TS学习】(15)分布式条件特性
前端·学习·typescript
lalapanda2 小时前
UE5学习记录 part13
学习·ue5
高林雨露2 小时前
Java对比学习Kotlin的详细指南(一)
java·学习·kotlin
jiet_h3 小时前
深入解析KSP(Kotlin Symbol Processing):现代Android开发的新利器
android·开发语言·kotlin
齐尹秦3 小时前
HTML5 Web Workers 学习笔记
笔记·学习
DarkBule_3 小时前
零基础驯服GitHub Pages
css·学习·html·github·html5·web
余多多_zZ3 小时前
鸿蒙学习手册(HarmonyOSNext_API16)_应用开发UI设计:Swiper
学习·ui·华为·harmonyos·鸿蒙系统
淬渊阁4 小时前
汇编学习之《扩展指令指针寄存器》
汇编·学习