kotlin列表过滤器与列表转换器

558 阅读3分钟

列表过滤器

列表过滤器是一种基于某些条件快速获取部分列表的方法。

比如我们需要查找一个数组中所有的偶数,我们可以这么写

val list = listOf(1, 2, 3, 4, 11, 12, 13, 14)
println(list.filter { num: Int -> num % 2 == 0 })

list.filter花括号中的过滤器条件会在循环时检查每一个列表项。如果表达式返回了 true,则结果中就会包含该列表项。输出结果如下:

[2, 4, 12, 14]

只包含一个参数的函数字面量不需要我们显式定义参数,我们可以直接使用该参数。 如果函数字面量中只有一个参数,我们可以省略它的声明以及 “->” 符号。该参数会被隐式地声明为 it。 由于我们不再需要定义参数名称,从而使得诸如过滤器一类的语言结构更加易于使用。

上面的写法等价于:

println(list.filter { it % 2 == 0 })
//输出 => [2, 4, 12, 14]

积极与惰性过滤器

积极:无论结果是否被使用都会触发。

惰性:只有在运行时且被需要时才会触发。

积极过滤器

在kotlin中,默认的过滤器都是积极过滤器,每当使用过滤器的时候,都会创建一个新的列表。

比如我们要寻找所有包含张姓的人名

val list= listOf("张三","李四","王五","赵六")
println(list.filter { it.contains("张") })

//输出 => [张三]

堕性过滤器

序列是一种使用惰性求值的数据结构,配合过滤器使用时可使过滤器转为惰性。惰性过滤器会增加额外的性能损耗,所以在操作大型集合并且不需要全部结果时才比较有用。

上面的例子我们稍作修改

val list= listOf("张三","李四","王五","赵六")
println(list.asSequence().filter { it.contains("张") })

//输出 => kotlin.sequences.FilteringSequence@5315b42e

可以看到filter并没有返回一个新的列表,而是返回了一个含有列表元素及应用于元素的过滤器信息的序列。当我们访问其中元素时,才会应用过滤器并返回相应的结果。

序列可以使用toList()来转换成列表

val list= listOf("张三","李四","王五","赵六")
println(list.asSequence().filter { it.contains("张") }.toList())
//输出 => [张三]

列表转换器

map

map{} 可以对每一个列表项进行相同的转换并返回转换后的列表。

val numbers = listOf(1, 2, 3)
println(numbers.map { it * 3 })

//输 出 => [3, 6, 9]

配合列表过滤器可以很方便的实现一些操作,比如我们要获取学生中分数大于60分的学生id

val students = arrayListOf<Student>()
students.add(Student(1, "张三", 70))
students.add(Student(2, "李四", 80))
students.add(Student(3, "王五", 30))
students.add(Student(4, "赵六", 20))
println(students.filter { it.score > 60 }.map { it.sName })

//输出 => [张三, 李四]

flatten

flatten()返回一个包含了嵌套集合内的所有元素的列表。

val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5), setOf("张三", "李四"))
println(numberSets.flatten())

//输出 => [1, 2, 3, 4, 5, 张三, 李四]