Kotlin标准库函数
在 Kotlin 源码的Standard.kt标准库中提供了一些便捷的内置高阶函数如 apply 、let、run、with、also、takelf,可以帮助我们写出更简洁优雅的 Kotlin 代码,提高开发效率。如果对kotlin高阶函数不了解的请先前往Android学习Kotlin之常量、条件、函数、高阶函数中查看。
其它Kotlin文章
Android学习Kotlin之一、常量-条件-函数-高阶函数
Android学习Kotlin之二、Null安全 -字符串操作- 类型转换
Android学习Kotlin之三、标准库函数-集合List-Set-Map
Android学习Kotlin之四、定义类-初始化-继承
Android学习Kotlin之五、对象-接口-抽象类
Android学习Kotlin之六、泛型-扩展函数
本编文章会讲到的知识点
- 标准库函数
- apply
- let
- apply和let区别
- run
- with
- also
- takelf
- takeUnless
- 总结
- 集合
- List
- Set
- Map
标准库函数
apply
apply函数可看作一个配置 函数,你可以传入一个接收者,然后调用一系列函数来配置它以便使用,如果提供lambda给apply函数执行,它会返回配置好的接收者。
下面代码可以看到,调用一个函数类配置接收者时,变量名就省掉了,这是因为,在lambda表达式里,apply能让每个配置函数都作用于接收者,这种行为有时又叫做,因为lambda表达式里的所有函数调用都是针对接收者的,或者说,它们是针对接收者的。
// 设置user对象 先创建一个user对象 然后通过对象名配置属性
val user = User()
user.age = 18
user.name = "刘德华"
println(user.toString())//年龄 18 名字 刘德华
// 通过apply来隐式的配置属性 lamdba中对象引用是this
val user2 = User().apply {
age = 16
name = "刘亦菲"
}
println(user2)//年龄 16 名字 刘亦菲
let
let函数能使某个变量作用于其lambda表达式里,让it关键字能引用它。let与apply比较,let会 把接收者传给lambda,而apply什么 都不传,匿名函数执行完,apply会返回当前接收者,而let会 返回lambda的最后一行。
val user = User().let {
it.age = 12
it.name = "张硕硕"
it
}
println(user.toString())//年龄 12 名字 张硕硕
apply和let区别
- let会把接收者对象传给lambda表达式,而apply不会
- let返回的是lambda表达式最后一行,apply返回的是当前接收者
run
光看作用域行为,run和apply差不多,但与apply不同,run函数不返回接收者,run返回的是lambda结果,也就是true或 者false。
val user = User()
user.age = 12
val run = user.run {
age === 10
}
println(run)// false
- run也可以执行函数引用
fun isLong(name: String) = name.length > 10
fun priStr(isLong: Boolean) {
println(if (isLong) "1111" else "0000")// 1111
}
// run也可以执行函数引用
"We are family".run(::isLong)//把字符串传过去接收一个布尔值
.run(::priStr)// 把上一个run返回布尔值传过去
with
with函数是run的变体,他们的功能行为是一样的,但with的调用 方式不同,调用with时需要值参作为其第一个参数传入。
//with函数的功能和run基本一样,唯一不同就是调用方式不同,with需要传入值参
val user = User()
val with = with(user) {
age === 10
}
println(with)// false
also
also函数和let函数功能基本一样,不同的是also返回的是接收者对象,而let返回的是lambda表达式最后一行,基于also返回接收者对象,我们可以通过also做基于原始对象的一些链式调用。
val user = User().also {
it.age=10
}.also {
it.name = "鹿晗"
}
println(user.toString())// 年龄 10 名字 鹿晗
takelf
takeIf函数根据lambda表达式内的条件语句给出的true或者false,如果是true就返回接收者对象,如果是false就返回null,功能来看和if语句类似,优点在于可以直接在对象实例调用,不需要再变量赋值。
val user = User()
user.age = 10
user.name = "张艺兴"
val n = user.takeIf {
it.age === 10
}?.name
println(n)// 张艺兴
takeUnless
takeUnless函数和takeIf函数辅助使用,takeUnless函数使lambda表达式里的条件语句返回false时返回接收对象。
val n = User().takeUnless {
it.age===10
}?.name
println(n)//迪丽热巴
总结
函数 | 对象引用 | 返回值 |
---|---|---|
let | it | lambda result |
run | this | lambda result |
with | this | lambda result |
apply | this | Context object |
also | it | Context object |
集合
集合可以方便你处理一-组数据,也可以作为值参传给函数,和我们学过的其他变量类型一样,List、Set和Map类型的变量也分为两类,只读和可变。
List
List的创建和元素获取
- 创建list,listOf不可变集合 只读
val mList:List<String> = listOf("HTML","VUE","Kotlin","JAVA")
- get(index) 通过下标获取元素,如果下标越界会报错。
println(mList.get(2))//Kotlin
println(mList.get(4))//报错下标越界 java.lang.ArrayIndexOutOfBoundsException: 4
- getOrEIse获取元素是一一个安全索引取值函数,它需要两个参数,第一个是索引值,第二个是能提供默认值的lambda表达式,如果索引值不存在的话,可用来代替异常。
println(mList.getOrElse(4){"notfind"})//notfind
- getOrNull是Kotlin提供的另-一个安全索引取值函数,它返回null结果,而不是抛出异常。
println(mList.getOrNull(4))// null
println(mList.getOrNull(4) ?: "notfind")//notfind
可变集合
在Kotlin中,支持内容修改的列表叫可变列表,要创建可变列表,可以使用mutableListOf函数。List还 支持使用toList和toMutableList函数动态实现只读列表和可变列表的相互转换。
- 创建可变集合
val mutableList: MutableList<String> = mutableListOf("HTML", "VUE", "Kotlin", "JAVA")
- 增加元素和移除元素
mutableList.add(0, "Android")//在哪个下标插入
// mutableList.add("Android")//在最后插入
println(mutableList)//[Android, HTML, VUE, Kotlin, JAVA]
// mutableList.remove("VUE")//根据元素移除
mutableList.removeAt(1)//根据下标移除
println(mutableList)//[Android, VUE, Kotlin, JAVA]
- 只读集合和可变集合互换,使用toList和toMutableList函数。
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函数
能修改可变集合的函数成为mutator函数
- 添加元素运算符与删除元素运算符
val mutableList2: MutableList<String> = mutableListOf("HTML", "VUE", "Kotlin", "JAVA")
mutableList2 += "Android"//添加元素
println(mutableList2)// [HTML, VUE, Kotlin, JAVA, Android]
mutableList2 -= "Android"//移除元素
println(mutableList2)// [HTML, VUE, Kotlin, JAVA]
- 基于lambda表达式指定的条件删除元素
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表达式返回it
list.forEach {
println(it+"-")
}
- forEachIndexed 遍历获取索引
list.forEachIndexed { index, item ->
println("index=${index} item=${item}")
}
解构 通过_符号过滤不想要的元素
val (html:String,vue:String,_:String,java:String) = list
println("${html} ${vue} ${java}")//HTML VUE JAVA
Set
Set创建和获取元素
- 使用setof创建不可变集合
val set:Set<String> = setOf("HTML", "VUE", "Kotlin", "JAVA")
- 获取元素elementAt() 和list获取元素类似
println(set.elementAt(1))//正常获取元素
println(set.elementAt(4))//下标越界 报错java.lang.IndexOutOfBoundsException
println(set.elementAtOrElse(4){"nofind"})//如果找不到走lambder表达式
println(set.elementAtOrNull(4)?:"isNULL")//如果找不到返回Null
增加元素和移除元素
set集合中不会存在相同的元素
mutableSet.add("JS")//新增
mutableSet.remove("VUE")//移除
mutableSet+="Android"//新增
mutableSet+="Kotlin"//集合中已有Kotlin就不会加进去了
mutableSet-="HTML"//移除
集合转换
val toMutableSet = set.toMutableSet()//转可变集合
toMutableSet+="Android"
println(toMutableList)
val toSet = mutableSet.toSet()//转不可变集合
println(toSet)
//list集合转set集合
val toSet1 = list.toSet()
val toMutableSet1 = list.toMutableSet()
//set集合转list集合
val toList1 = set.toList()
val toMutableList1 = set.toMutableList()
Map
map的创建
to看上去像关键字,但事实上,它是个省略了点号和参数的特殊函数,to函数将它左边和右边的值转化成一对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]根据key获取值,读取键对应的值,如果键不存在就返回null
println(map["马化腾"])//18
//getValue(key) 根据key获取值,如果键不存在就抛出异常
println(map.getValue("马云"))//20
//getOrElse,读取键对应的值,或者使用匿名函数返回默认值
println(map.getOrElse("马赛克"){"unknown"})//unknown
//getOrDefault,读取键对应的值,或者返回默认值
println(map.getOrDefault("马赛克",0))//0
可变MutableMap
val mutableMap: MutableMap<String, Int> = mutableMapOf("马云" to 20, "马化腾" to 18, "黄征" to 22)
mutableMap += "刘强东" to 19
mutableMap.put("黄晓明", 6)
mutableMap -= "马化腾"
mutableMap.remove("马云")
println(mutableMap)//{黄征=22, 刘强东=19, 黄晓明=6}
getOrPut
getOrPut(key){n} 如果获取的Key没有,就先添加再返回,否则返回相应的值
//案例结合上面的可变map数据
println(mutableMap.getOrPut("老王") { 1 })//因为没有老王 就先添加到map中
println(mutableMap)//{黄征=22, 刘强东=19, 黄晓明=6, 老王=1}
遍历
-
forEach 返回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}")
}