map(transform: (T) -> R): List<R>
这个函数内部调用的是
public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}
这里的mapTo函数定义如下:
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C {
for (item in this)
destination.add(transform(item))
return destination
}
我们可以看出,这个map实现的原理是循环遍历原集合中的元素,并把通过transform映射后的结果放到一个新的destination集合中,并返回destination。
mapIndexed(transform: (kotlin.Int, T) -> R)
转换函数transform
中带有下标参数。也就是说我们可以同时使用下标和元素的值来进行转换。 其中,第一个参数是Int类型的下标。
代码示例:
mapNotNull(transform: (T) -> R?)
代码示例:
[a, b, x, z]
这个函数内部实现是调用的mapNotNullTo
函数:
public inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
forEach { element -> transform(element)?.let { destination.add(it) } }
return destination
}
flatMap(transform: (T) -> Iterable<R>): List<R>
在原始集合的每个元素上调用transform
转换函数,得到的映射结果组成的单个列表。为了更简单的理解这个函数,我们跟map(transform: (T) -> R): List<R>
对比下。
首先看函数的各自的实现:
map:
public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R> {
return flatMapTo(ArrayList<R>(), transform)
}
public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.flatMapTo(destination: C, transform: (T) -> Iterable<R>): C {
for (element in this) {
destination.addAll(list)
return destination
}
我们可以看出,这两个函数主要区别在transform函数返回上。
代码示例
>>> val list = listOf("a","b","c")
>>> list.map({it->listOf(it+1,it+2,it+3)})
[[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]]
>>> list.flatMap({it->listOf(it+1,it+2,it+3)})
[a1, a2, a3, b1, b2, b3, c1, c2, c3]
从代码运行结果我们可以看出,使用 map 是把list中的每一个元素都映射成一个List-n
,然后以这些List-n
为元素,组成一个大的嵌套的List
返回。而使用flatMap则是把list中的第一个元素映射成一个List1,然后把第二个元素映射成的List2跟List1合并:List1.addAll(List2)
,以此类推。最终返回一个“扁平的”(flat)List。
其实,这个flatMap的过程是 map + flatten
两个操作的组合。这个flatten函数定义如下:
代码示例:
>>> val list = listOf("a","b","c")
>>> list.map({it->listOf(it+1,it+2,it+3)})
[[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]]
[a1, a2, a3, b1, b2, b3, c1, c2, c3]