Android学习Kotlin之三、标准库函数-集合List-Set-Map

Kotlin标准库函数

在 Kotlin 源码的Standard.kt标准库中提供了一些便捷的内置高阶函数如 apply 、let、run、with、also、takelf,可以帮助我们写出更简洁优雅的 Kotlin 代码,提高开发效率。如果对kotlin高阶函数不了解的请先前往Android学习Kotlin之常量、条件、函数、高阶函数中查看。

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能让每个配置函数都作用于接收者,这种行为有时又叫做\color{red} {相关作用域},因为lambda表达式里的所有函数调用都是针对接收者的,或者说,它们是针对接收者的\color{red} {隐式调用}

        // 设置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区别

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


    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}")
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容