美文网首页最适合Android程序员的kotlin笔记
最适合Android程序员的kotlin笔记——集合操作

最适合Android程序员的kotlin笔记——集合操作

作者: 朱_c713 | 来源:发表于2019-12-31 17:46 被阅读0次

    一. 简要介绍

    整体特点

    • kotlin没有自己的集合类
    • kotlin的集合设计不同于java,kotlin将访问集合数据的接口,和修改集合数据的接口分开了。
    • kotlin中每一个集合都有一个对应的Mutable集合,他们分别来表示,只读集合和可变集合

    集合:

    val arr = arrayOf("1","2",3,4,5)
    val list1 = listOf(1,2,"3",4,"5") // 随意创建
    val list2 = listOf<String>("1","2","3","4","5") // 确定元素的值类型
    val list3 = listOf(arr) // 可传入一个数组

    map:

    map的遍历:

    • 使用map[key] 读取值
    • 使用map[key]=value 设置值

    集合函数示意:

    创建一个Person.kt 文件:

    data class Person(val name:String,val age:Int)
    

    集合处理代码:

     val people = listOf(Person("Alice", 29), Person("Bob", 31))
     print(people.maxBy { it.age })
    print(people.maxBy(Person::age))
    
    

    打印内容:

     Person(name=Bob,age=31)
     Person(name=Bob,age=31)
    

    二. 高阶技巧

    基础:filter和map

    • filter和map函数形成了函数操作的基础
    1. 示例,过滤出偶数:
     val list = listOf(1, 2, 3, 4)
    print(list.filter { it % 2 == 0 })
    
    2. 示例,过滤出年龄大约三十的对象
     val people = listOf(Person("Alice", 29), Person("Bob", 31))
     print(people.filter { it.age > 30 })
    
    • filter 函数可以从集合中移除你不想要的元素,但是并不会改变这些元素。
    • 元素变化是map的用武之地
      示例:
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
     LogUtils.d("vvvvvvvvvvvvvvv",people.filter { it.age > 30 })
    LogUtils.d("vvvvvvvvvvvvvvv",people)
    

    运行结果:

    [Person(name=Bob, age=31)]
    [Person(name=Alice, age=29), Person(name=Bob, age=31)]
    

    结果:

    [1, 4, 9, 16]
    [1, 2, 3, 4]
    
    3. 打印对象集合中,某一个属性的列表
           val people = listOf(Person("Alice", 29), Person("Bob", 31))
            LogUtils.d("vvvvvvvvvvvvvvv",people.map { it.name })
    

    结果:

    [Alice, Bob]
    
    4. 组合使用(打印出年龄超过三十岁的人的名字)
     val people = listOf(Person("Alice", 29), Person("Bob", 31))
    people.filter { it.age>30 }.map { it.name }
    

    结果:

    [Bob]
    
    5.filter与函数相结合:(获取对象集合中年龄最大的人的名字:)
    val people = listOf(Person("Alice", 29), Person("Bob", 31))
    LogUtils.d("vvvv", people.filter { it.age == people.maxBy { it.age }.age })
    LogUtils.d("vvvv", people.filter { it.age == people.maxBy(Person::age).age })
    

    以为编译器报非空的问题,所以可以加上强制不为空

      LogUtils.d("vvvv", people.filter { it.age == people.maxBy(Person::age)!!.age })
    

    双it写法也容易让引起代码不容易读的问题,编译器会提示,更改:

      LogUtils.d("vvvv", people.filter { it.age == people.maxBy { person -> person.age }!!.age })
    
    • filter内部其实是有一个循环在进行着,以上写法可能导致性能问题:
      推荐:
      val maxAge=people.maxBy(Person::age)!!.age
      people.filter{it.age==maxAge}
      最终代码:
     val people = listOf(Person("Alice", 29), Person("Bob", 31),Person("Job", 31))
    val maxAge=people.maxBy(Person::age)!!.age
     LogUtils.d("vvvv", people.filter{it.age==maxAge})
    

    使用判断式+(all any count find)

    定义一个判断式,年龄小于27:

      val ageUnder27 = { p: Person -> p.age <= 27 }
    
    • count 函数检查有多少个元素满足判断式
    • find函数返回第一个符合条件的元素
    • all 是否所有元素都满足判断式
    • any 集合中是否至少存在一个匹配的元素
    val people = listOf(Person("Alice", 27), Person("Bob", 31), Person("Job", 11))
    val ageUnder27 = { p: Person -> p.age <= 27 }
    LogUtils.d("vvvv", people.count(ageUnder27) )
    

    结果:2

    列表转换成分组的元素

     val people = listOf(Person("Alice", 27), Person("Bob", 31), Person("Job", 11), Person("Li", 31))
    val ageUnder27 = { p: Person -> p.age <= 27 }
    LogUtils.d("vvvv", people.groupBy { it.age })
    LogUtils.d("vvvv", people.groupBy(ageUnder27))
    

    注意分组结果是map,以年龄对应的map 和以false true对应的map,结果类型:Map<Int,List<Person>>

    {27=[Person(name=Alice, age=27)], 31=[Person(name=Bob, age=31), Person(name=Li, age=31)], 11=[Person(name=Job, age=11)]}
    {true=[Person(name=Alice, age=27), Person(name=Job, age=11)], false=[Person(name=Bob, age=31), Person(name=Li, age=31)]}
    

    处理嵌套集合中的元素:flatMap 和flatten

    集合改写错误:

          val result: MutableList<RecordPlayBean.DetailBean> = historyData as MutableList<RecordPlayBean.DetailBean>
                val it =  result.iterator()
                while (it.hasNext()) {
                    val massage = it.next()
                    if (massage.isSelect) {
                        it.remove()
                    }
                }
    

    改写成:

     historyData.filter { !it.isSelect }
    

    结果改写错误,下面的代码,返回的仍然是historyData本身。上面的那个,可以返回筛选后的结果。

    相关文章

      网友评论

        本文标题:最适合Android程序员的kotlin笔记——集合操作

        本文链接:https://www.haomeiwen.com/subject/xwcioctx.html