# 1. 前言
`Kotlin`官方提供了一些定义好的高阶函数,方便使用。`Kotlin`标准库定义了大量的对于集合操作的函数,在本节中我们将选取一些常用、具有代表性的函数进行讲解。
# 2. 查找
![](https://img.kancloud.cn/a7/6e/a76e8e2be34b98326afe056ae237c197_966x519.png)
上图来源:[Kotlin从基础到实战-黑马程序员编著-微信读书 (qq.com)](https://weread.qq.com/web/reader/ab3320e0718ade85ab3fd1cka87322c014a87ff679a21ea)
用法其实都差不多这里仅做一个示范:
~~~
fun main() {
var list = listOf<Int>(3, 4, 1, 3)
println("列表中第一个大于3的元素:${list.find { it > 3 }}")
}
~~~
结果:
```
列表中第一个大于3的元素:4
```
又比如:
~~~
fun main() {
var list = listOf<Int>(3, 4, 1, 3, -3, -5, 0, 2, -1)
println("列表中大于0的元素:${list.filter { it > 0 }}")
}
~~~
结果:
```
列表中大于0的元素:[3, 4, 1, 3, 2]
```
值得注意的是,方法声明为:
```
Iterable<T>.xxx
```
我们可以进行仿写一个`find`方法:
~~~
fun <T> Iterable<T>.myFind(function: (a: T) -> Boolean): T? {
for(ele in this){
if(function(ele)){
return ele
}
}
return null
}
fun main() {
var list = listOf(3, 4, 1, 3, -3, -5, 0, 2, -1)
println("列表中第一个大于3的元素:${list.myFind { it > 3 }}")
}
~~~
结果:
```
列表中第一个大于3的元素:4
```
这里的写法就比较类似于在`JavaScript`中的原型方法,只要定义在这个原型链上,就可以使用。至于其余的查找方法这里就不再一一给出案例。
# 3. 比较
~~~
fun main() {
var list = listOf(3, 4, 1, 3, -3, -5, 0, 2, -1)
println(list.maxBy { it })
println(list.minBy { it })
println(list.distinctBy { it })
}
~~~
结果:
```
4
-5
[3, 4, 1, -3, -5, 0, 2, -1]
```
# 4. 标准库中的高阶函数
![](https://img.kancloud.cn/a0/0f/a00f47566a55896d13c7123365ae3a83_958x658.png)
## 4.1 repeat
~~~
fun main() {
repeat(3, {
println("Hello world.")
})
}
~~~
结果:
```
Hello world.
Hello world.
Hello world.
```
## 4.2 run
~~~
fun main() {
var list = mutableListOf<Int>()
run {
list.add(2)
list.add(3)
}
println(list)
}
~~~
结果:
```
[2, 3]
```
## 4.3 其他常见标准函数
### 4.3.1 apply
~~~
fun main() {
var list = mutableListOf<Int>(3, 2, 4, 1)
list = list.apply {
//todo this为当前list
}
println(list)
}
~~~
### 4.3.2 let
~~~
fun main() {
// 定义一个可以为空的字符串
var a: String? = "Hello"
a = a?.let {
// 如果不是空白字符串
if(it.isNotBlank()){
it.toUpperCase()
} else{
"Hello"
}
}
println(a)
}
~~~
结果:
```
HELLO
```
### 4.3.3 let
~~~
fun main() {
var session: String? = null
var msg = session?.let {
"Welcome!"
} ?: "Not login yet."
println(msg)
}
~~~
结果:
```
Not login yet.
```
### 4.3.4 run
~~~
fun main() {
var session: String? = "Message"
var msg = session?.run {
contains("M")
}
println(msg)
}
~~~
结果
```
true
```
### 4.3.5 also
在前面的案例中,我们可以使用`run`或者`apply`来进行应用一些操作。但是,有些时候,我们需要在同一原始对象上做不同的操作,就可以使用`also`来实现。比如下面的案例:
~~~
fun main() {
var username = "danjffkdfjk"
username?.also {
it.run(::process)
.run(::isToLong)
.run(::getMessage)
.run(::println)
}.also {
println("原始字符串内容为:${it}")
}
}
~~~
结果:
```
用户名过长!
原始字符串内容为:danjffkdfjk
```
### 4.3.6 takeIf
类似于`if`,但是可以直接作用于对象上,比较方便。当判断`lambda`表达式为`true`返回接受者对象,否者返回`null`。比如下面的案例:
~~~
fun main() {
var file: File? = File("./Coding/src/main/java/com/kotlinLearn/a.txt")
// 使用takeIf来判断一下文件是否可读
var content = file?.takeIf { it.canRead() }
?.readText()
println(content)
}
~~~
结果输出文件内容。
对于这个功能,其最终会转换为:
```
File var10000 = file.canRead() ? file : null;
```
不妨在`IDEA`中使用`SHIFT`进行搜索`show kotlin ByteCode`,然后点击`Decompile`可以看到生成的代码:
![](https://img.kancloud.cn/eb/61/eb61e95705e418007f4035268db65681_368x126.png)
### 4.3.7 综合案例
~~~
fun isToLong(string: String):Boolean{
return string.length > 5
}
fun main() {
var username = "danjffkdfjk"
username?.let {
if(it.isNotBlank()) {
it.toUpperCase()
} else{
"Empty!"
}
}.run(::isToLong).apply {
if(this){
println("用户名过长!")
} else{
println("用户名满足条件")
}
}
}
~~~
结果:
```
用户名过长!
```
当然,我们可以让代码更加规范:
~~~
fun process(string: String): String {
if (string.isNotBlank()) {
return string.toUpperCase()
}
return "Empty!"
}
fun isToLong(string: String): Boolean {
return string.length > 5
}
fun getMessage(boolean: Boolean): String {
if (boolean) {
return "用户名过长!"
}
return "用户名满足条件"
}
fun main() {
var username = "danjffkdfjk"
username?.run(::process)
.run(::isToLong)
.run(::getMessage)
.run(::println)
}
~~~
结果是一样的,只是这里将功能抽离为了方法。然后使用`::`来进行引用。
- Kotlin语言基础
- Kotlin的简介
- Kotlin的变量和常见数据类型
- Kotlin的区间
- Kotlin的位运算
- Kotlin的容器
- Kotlin类型检查
- Kotlin的空值处理
- Kotlin的函数
- Kotlin的类
- Kotlin的委托
- Kotlin的延迟加载
- Kotlin的异常
- Kotlin的Lambda表达式
- Kotlin的高阶函数
- Kotlin的标准库中的高阶函数
- Kotlin的泛型
- Kotlin的表达式
- Kotlin的解构
- Kotlin的运算符重载
- Kotlin语言中级
- Kotlin的扩展函数
- Kotlin的扩展属性
- Kotlin的infix关键字
- Kotlin的DSL
- Kotlin的一些注解(和Java互调用)
- Kotlin的lateinit和by lazy
- Kotlin的反射
- Kotlin的匿名接口
- 安卓中的Kotlin
- 数据库操作Room