一. 简要介绍
整体特点
- 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
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
{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 = historyData as MutableList
val it = result.iterator()
while (it.hasNext()) {
val massage = it.next()
if (massage.isSelect) {
it.remove()
}
}
改写成:
historyData.filter { !it.isSelect }
结果改写错误,下面的代码,返回的仍然是historyData本身。上面的那个,可以返回筛选后的结果。