Kotlin標(biāo)準(zhǔn)庫函數(shù)
在 Kotlin 源碼的Standard.kt標(biāo)準(zhǔn)庫中提供了一些便捷的內(nèi)置高階函數(shù)如 apply 、let、run、with、also、takelf,可以幫助我們寫出更簡潔優(yōu)雅的 Kotlin 代碼,提高開發(fā)效率。如果對(duì)kotlin高階函數(shù)不了解的請(qǐng)先前往Android學(xué)習(xí)Kotlin之常量、條件、函數(shù)、高階函數(shù)中查看。

其它Kotlin文章
Android學(xué)習(xí)Kotlin之一、常量-條件-函數(shù)-高階函數(shù)
Android學(xué)習(xí)Kotlin之二、Null安全 -字符串操作- 類型轉(zhuǎn)換
Android學(xué)習(xí)Kotlin之三、標(biāo)準(zhǔn)庫函數(shù)-集合List-Set-Map
Android學(xué)習(xí)Kotlin之四、定義類-初始化-繼承
Android學(xué)習(xí)Kotlin之五、對(duì)象-接口-抽象類
Android學(xué)習(xí)Kotlin之六、泛型-擴(kuò)展函數(shù)
本編文章會(huì)講到的知識(shí)點(diǎn)
- 標(biāo)準(zhǔn)庫函數(shù)
- apply
- let
- apply和let區(qū)別
- run
- with
- also
- takelf
- takeUnless
- 總結(jié)
- 集合
- List
- Set
- Map
標(biāo)準(zhǔn)庫函數(shù)
apply
??apply函數(shù)可看作一個(gè)配置 函數(shù),你可以傳入一個(gè)接收者,然后調(diào)用一系列函數(shù)來配置它以便使用,如果提供lambda給apply函數(shù)執(zhí)行,它會(huì)返回配置好的接收者。
??下面代碼可以看到,調(diào)用一個(gè)函數(shù)類配置接收者時(shí),變量名就省掉了,這是因?yàn)椋趌ambda表達(dá)式里,apply能讓每個(gè)配置函數(shù)都作用于接收者,這種行為有時(shí)又叫做,因?yàn)閘ambda表達(dá)式里的所有函數(shù)調(diào)用都是針對(duì)接收者的,或者說,它們是針對(duì)接收者的
。
// 設(shè)置user對(duì)象 先創(chuàng)建一個(gè)user對(duì)象 然后通過對(duì)象名配置屬性
val user = User()
user.age = 18
user.name = "劉德華"
println(user.toString())//年齡 18 名字 劉德華
// 通過apply來隱式的配置屬性 lamdba中對(duì)象引用是this
val user2 = User().apply {
age = 16
name = "劉亦菲"
}
println(user2)//年齡 16 名字 劉亦菲
let
let函數(shù)能使某個(gè)變量作用于其lambda表達(dá)式里,讓it關(guān)鍵字能引用它。let與apply比較,let會(huì) 把接收者傳給lambda,而apply什么 都不傳,匿名函數(shù)執(zhí)行完,apply會(huì)返回當(dāng)前接收者,而let會(huì) 返回lambda的最后一行。
val user = User().let {
it.age = 12
it.name = "張碩碩"
it
}
println(user.toString())//年齡 12 名字 張碩碩
apply和let區(qū)別

- let會(huì)把接收者對(duì)象傳給lambda表達(dá)式,而apply不會(huì)
- let返回的是lambda表達(dá)式最后一行,apply返回的是當(dāng)前接收者
run
光看作用域行為,run和apply差不多,但與apply不同,run函數(shù)不返回接收者,run返回的是lambda結(jié)果,也就是true或 者false。
val user = User()
user.age = 12
val run = user.run {
age === 10
}
println(run)// false
- run也可以執(zhí)行函數(shù)引用
fun isLong(name: String) = name.length > 10
fun priStr(isLong: Boolean) {
println(if (isLong) "1111" else "0000")// 1111
}
// run也可以執(zhí)行函數(shù)引用
"We are family".run(::isLong)//把字符串傳過去接收一個(gè)布爾值
.run(::priStr)// 把上一個(gè)run返回布爾值傳過去
with
with函數(shù)是run的變體,他們的功能行為是一樣的,但with的調(diào)用 方式不同,調(diào)用with時(shí)需要值參作為其第一個(gè)參數(shù)傳入。
//with函數(shù)的功能和run基本一樣,唯一不同就是調(diào)用方式不同,with需要傳入值參
val user = User()
val with = with(user) {
age === 10
}
println(with)// false
also
also函數(shù)和let函數(shù)功能基本一樣,不同的是also返回的是接收者對(duì)象,而let返回的是lambda表達(dá)式最后一行,基于also返回接收者對(duì)象,我們可以通過also做基于原始對(duì)象的一些鏈?zhǔn)秸{(diào)用。
val user = User().also {
it.age=10
}.also {
it.name = "鹿晗"
}
println(user.toString())// 年齡 10 名字 鹿晗
takelf
takeIf函數(shù)根據(jù)lambda表達(dá)式內(nèi)的條件語句給出的true或者false,如果是true就返回接收者對(duì)象,如果是false就返回null,功能來看和if語句類似,優(yōu)點(diǎn)在于可以直接在對(duì)象實(shí)例調(diào)用,不需要再變量賦值。
val user = User()
user.age = 10
user.name = "張藝興"
val n = user.takeIf {
it.age === 10
}?.name
println(n)// 張藝興
takeUnless
takeUnless函數(shù)和takeIf函數(shù)輔助使用,takeUnless函數(shù)使lambda表達(dá)式里的條件語句返回false時(shí)返回接收對(duì)象。
val n = User().takeUnless {
it.age===10
}?.name
println(n)//迪麗熱巴
總結(jié)
| 函數(shù) | 對(duì)象引用 | 返回值 |
|---|---|---|
| let | it | lambda result |
| run | this | lambda result |
| with | this | lambda result |
| apply | this | Context object |
| also | it | Context object |
集合
集合可以方便你處理一-組數(shù)據(jù),也可以作為值參傳給函數(shù),和我們學(xué)過的其他變量類型一樣,List、Set和Map類型的變量也分為兩類,只讀和可變。
List
List的創(chuàng)建和元素獲取
- 創(chuàng)建list,listOf不可變集合 只讀
val mList:List<String> = listOf("HTML","VUE","Kotlin","JAVA")
- get(index) 通過下標(biāo)獲取元素,如果下標(biāo)越界會(huì)報(bào)錯(cuò)。
println(mList.get(2))//Kotlin
println(mList.get(4))//報(bào)錯(cuò)下標(biāo)越界 java.lang.ArrayIndexOutOfBoundsException: 4
- getOrEIse獲取元素是一一個(gè)安全索引取值函數(shù),它需要兩個(gè)參數(shù),第一個(gè)是索引值,第二個(gè)是能提供默認(rèn)值的lambda表達(dá)式,如果索引值不存在的話,可用來代替異常。
println(mList.getOrElse(4){"notfind"})//notfind
- getOrNull是Kotlin提供的另-一個(gè)安全索引取值函數(shù),它返回null結(jié)果,而不是拋出異常。
println(mList.getOrNull(4))// null
println(mList.getOrNull(4) ?: "notfind")//notfind
可變集合
在Kotlin中,支持內(nèi)容修改的列表叫可變列表,要?jiǎng)?chuàng)建可變列表,可以使用mutableListOf函數(shù)。List還 支持使用toList和toMutableList函數(shù)動(dòng)態(tài)實(shí)現(xiàn)只讀列表和可變列表的相互轉(zhuǎn)換。
- 創(chuàng)建可變集合
val mutableList: MutableList<String> = mutableListOf("HTML", "VUE", "Kotlin", "JAVA")
- 增加元素和移除元素
mutableList.add(0, "Android")//在哪個(gè)下標(biāo)插入
// mutableList.add("Android")//在最后插入
println(mutableList)//[Android, HTML, VUE, Kotlin, JAVA]
// mutableList.remove("VUE")//根據(jù)元素移除
mutableList.removeAt(1)//根據(jù)下標(biāo)移除
println(mutableList)//[Android, VUE, Kotlin, JAVA]
- 只讀集合和可變集合互換,使用toList和toMutableList函數(shù)。
val toMutableList = listOf<String>("HTML", "VUE", "Kotlin", "JAVA").toMutableList()
toMutableList.add("Android")
println(toMutableList)//[HTML, VUE, Kotlin, JAVA, Android]
val toList = mutableListOf<String>("HTML", "VUE", "Kotlin", "JAVA").toList()
// toList.add()//沒有add方法
println(toList)//[HTML, VUE, Kotlin, JAVA]
mutator函數(shù)
能修改可變集合的函數(shù)成為mutator函數(shù)
- 添加元素運(yùn)算符與刪除元素運(yùn)算符
val mutableList2: MutableList<String> = mutableListOf("HTML", "VUE", "Kotlin", "JAVA")
mutableList2 += "Android"http://添加元素
println(mutableList2)// [HTML, VUE, Kotlin, JAVA, Android]
mutableList2 -= "Android"http://移除元素
println(mutableList2)// [HTML, VUE, Kotlin, JAVA]
- 基于lambda表達(dá)式指定的條件刪除元素
mutableList2.removeIf {
it.contains("VUE")
}
println(mutableList2)//[HTML, Kotlin, JAVA]
集合遍歷
- for in 遍歷
val list:List<String> = listOf("HTML", "VUE", "Kotlin", "JAVA")
for (item in list){
println(item)
}
- forEach 遍歷 lambder表達(dá)式返回it
list.forEach {
println(it+"-")
}
- forEachIndexed 遍歷獲取索引
list.forEachIndexed { index, item ->
println("index=${index} item=${item}")
}
解構(gòu) 通過_符號(hào)過濾不想要的元素
val (html:String,vue:String,_:String,java:String) = list
println("${html} ${vue} ${java}")//HTML VUE JAVA
Set
Set創(chuàng)建和獲取元素
- 使用setof創(chuàng)建不可變集合
val set:Set<String> = setOf("HTML", "VUE", "Kotlin", "JAVA")
- 獲取元素elementAt() 和list獲取元素類似
println(set.elementAt(1))//正常獲取元素
println(set.elementAt(4))//下標(biāo)越界 報(bào)錯(cuò)java.lang.IndexOutOfBoundsException
println(set.elementAtOrElse(4){"nofind"})//如果找不到走lambder表達(dá)式
println(set.elementAtOrNull(4)?:"isNULL")//如果找不到返回Null
增加元素和移除元素
set集合中不會(huì)存在相同的元素
mutableSet.add("JS")//新增
mutableSet.remove("VUE")//移除
mutableSet+="Android"http://新增
mutableSet+="Kotlin"http://集合中已有Kotlin就不會(huì)加進(jìn)去了
mutableSet-="HTML"http://移除
集合轉(zhuǎn)換
val toMutableSet = set.toMutableSet()//轉(zhuǎn)可變集合
toMutableSet+="Android"
println(toMutableList)
val toSet = mutableSet.toSet()//轉(zhuǎn)不可變集合
println(toSet)
//list集合轉(zhuǎn)set集合
val toSet1 = list.toSet()
val toMutableSet1 = list.toMutableSet()
//set集合轉(zhuǎn)list集合
val toList1 = set.toList()
val toMutableList1 = set.toMutableList()
Map
map的創(chuàng)建
to看上去像關(guān)鍵字,但事實(shí)上,它是個(gè)省略了點(diǎn)號(hào)和參數(shù)的特殊函數(shù),to函數(shù)將它左邊和右邊的值轉(zhuǎn)化成一對(duì)Pair
val map:Map<String,Int> = mapOf("馬云" to 20,"馬化騰" to 18, "黃征" to 22)
val mapOf = mapOf<String, Int>(Pair("托馬斯", 2), Pair("拜登", 3))
println(map)//{馬云=20, 馬化騰=18, 黃征=22}
println(mapOf)//{托馬斯=2, 拜登=3}
獲取元素
//[key]根據(jù)key獲取值,讀取鍵對(duì)應(yīng)的值,如果鍵不存在就返回null
println(map["馬化騰"])//18
//getValue(key) 根據(jù)key獲取值,如果鍵不存在就拋出異常
println(map.getValue("馬云"))//20
//getOrElse,讀取鍵對(duì)應(yīng)的值,或者使用匿名函數(shù)返回默認(rèn)值
println(map.getOrElse("馬賽克"){"unknown"})//unknown
//getOrDefault,讀取鍵對(duì)應(yīng)的值,或者返回默認(rèn)值
println(map.getOrDefault("馬賽克",0))//0
可變MutableMap
val mutableMap: MutableMap<String, Int> = mutableMapOf("馬云" to 20, "馬化騰" to 18, "黃征" to 22)
mutableMap += "劉強(qiáng)東" to 19
mutableMap.put("黃曉明", 6)
mutableMap -= "馬化騰"
mutableMap.remove("馬云")
println(mutableMap)//{黃征=22, 劉強(qiáng)東=19, 黃曉明=6}
getOrPut
getOrPut(key){n} 如果獲取的Key沒有,就先添加再返回,否則返回相應(yīng)的值
//案例結(jié)合上面的可變map數(shù)據(jù)
println(mutableMap.getOrPut("老王") { 1 })//因?yàn)闆]有老王 就先添加到map中
println(mutableMap)//{黃征=22, 劉強(qiáng)東=19, 黃曉明=6, 老王=1}
遍歷
-
forEach 返回it
it
mutableMap.forEach {
println(it)
}
- forEach 返回key value值
mutableMap.forEach { key, value ->
println("${key} ${value}")
}
- for in返回key value值
for ((key, value) in mutableMap) {
println("${key} ${value}")
}
