# 1. 前言
`Kotlin`官方提供了一些定義好的高階函數,方便使用。`Kotlin`標準庫定義了大量的對于集合操作的函數,在本節中我們將選取一些常用、具有代表性的函數進行講解。
# 2. 查找

上圖來源:[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. 標準庫中的高階函數

## 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`可以看到生成的代碼:

### 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