65.集合常用操作
2019-10-06 本文已影响0人
写代码的向日葵
1.集合过滤
fun main(args: Array<String>) {
val list1 = listOf<String>("张三", "李四", "王五", "找六", "张四", "李五", "李六")
val list2 = listOf<String>("周芷若", "张无忌", "张五", "李善长", "林青霞", "李寻欢")
//找到第一个集合中第一个姓张的
println(list1.find { it.startsWith("张") })
//把第一个集合中所有姓张的找出来
println(list1.filter { it.startsWith("张") })
//把两个集合中所有姓张的找出来并存放到一个集合中
val mutableList = mutableListOf<String>()
list1.filterTo(mutableList) { it.startsWith("张") }
list2.filterTo(mutableList) { it.startsWith("张") }
println(mutableList)
//把第一个集合中下标为偶数的过滤出来
println(list1.filterIndexed { index, value -> index % 2 == 0 })
}
2.集合排序
fun main(args: Array<String>) {
val list = listOf<String>("a", "b", "e", "f", "c", "g", "d")
//正序
println(list.sorted())
//倒序
println(list.sortedDescending())
val persons = listOf<Person>(Person("林青霞", 50), Person("张曼玉", 30), Person("柳岩", 70))
//排序
val sortedPerson = persons.sortedBy { it.age }
println(sortedPerson)
//倒序
println(persons.sortedByDescending { it.age })
}
data class Person(val name: String, val age: Int)
- sortedBy的实现如下:
image.png 可以看到sortedBy是一个
Iterable的扩展函数,也是一个高阶函数,接收的参数selector是一个函数类型,然后这个函数的参数是集合类型T,返回值是泛型R,R是一个实现了Comparable接口的泛型类型,所以上面可以使用it.age
3.分组
fun main(args: Array<String>) {
val list = listOf<String>("张三", "李四", "王五", "找六", "张四", "李五", "李六")
//分组
val map = list.groupBy {
val first = it.substring(0, 1)
when (first) {
"张" -> "张"
"李" -> "李"
else -> "其它"
}
}
}
- 输出结果如下:
image.png
groupBy源码分析:
a
b
c
- 调用顺序为
a->b->c,通过图a可以看到groupBy接收一个参数为T,返回值为K的函数类型的参数,然后调用图b中的函数,同时给了一个LinkedHashMap<K,MutableList<T>>作为第一个参数,看到图b的函数实现我们应该就明白了groupBy这个函数返回值k的作用了,继续看destination.getOrPut(key) { ArrayList<T>() },调用到图c,然后可以看到会从图a传递的LinkedHashMap<K,MutableList<T>>中通过key获取一个MutableList<T>,如果没有获取到,这个时候defaultValue: () -> V就起作用了,再看这个参数,原来是图b到图c的过程中传递的ArrayList<T>(),这样就形成了一个整体,根据key获取list,如果有就返回,如果没有则新创建一个,并且添加到LinkedHashMap<K,MutableList<T>>中,这样groupBy函数的返回值map就构建出来了- 图b中剩余的工作就是把遍历出来的元素添加到对应
key的list中,最后并且返回图a中构造出来的LinkedHashMap<K,MutableList<T>>
4.最值
fun main(args: Array<String>) {
val list = listOf<String>("a", "c", "b", "v", "f", "g", "e")
//最大值
println(list.max())
//最小值
println(list.min())
val persons = listOf<Person>(Person("林青霞", 50), Person("张曼玉", 30), Person("柳岩", 70))
//最大值
println(persons.maxBy { it.age })
//最小值
println(persons.minBy { it.age })
}
data class Person(val name: String, val age: Int)
- 具体的实现原理,与上面集合排序类似
5.去重复
fun main(args: Array<String>) {
val list = listOf<String>("a", "c", "b", "v", "f", "g", "e", "a", "c")
//去重复
val toSet = list.toSet()
println(toSet)
println(list.distinct())
val persons = listOf<Person>(
Person("林青霞", 50), Person("张曼玉", 30), Person("柳岩", 70), Person("张三", 90),
Person("张三", 20)
)
val distinctBy = persons.distinctBy { it.name.substring(0, 1) }
println(distinctBy)
}
data class Person(val name: String, val age: Int)
- 源码分析
distinctBy的参数是一个函数类型,和上面情况一样
image.png
- 可以看到去重主要是利用了
HashSet,而HashSet主要是对HashMap做了一层封装,看到只有set.add(key)为true的时候,才会将元素添加到集合中,HashSet的add函数调用的是HashMap的put函数,看到HashMap的最终实现如下:
a
b
HashSet的add为true的时候表明return map.put(e, PRESENT)==null成立,看到b图中,只有添加的元素不存在,为新元素的时候才为true,再倒回去看,这样就去重成功了,平时我们开发的时候,也值得借鉴这种思想。
image.png
可以看到sortedBy是一个
image.png
a
b
c
image.png
a
b