
kotlin扩展函数参考
映射(Mapping)
合并(Zipping)
关联(Association)
扁平化(Flattening)
字符串表达(String representation)
过滤(Filtering)集合
加法(Plus) 和 减法(Minus) 操作符
分组(Grouping)
Kotlin 标准库提供了一组扩展函数用于集合的 变换(Transformation). 这些函数会使用指定的变换规则从原集合创建新的集合. 本节中, 我们概要介绍集合的这些变换函数.
映射(Mapping)
映射(Mapping) 变换, 会将集合的每个元素传递给一个函数, 然后用函数结果创建一个新的集合. 最基本的映射函数是 map(). 它将每个元素传递给指定的 lambda 函数, 然后用 lambda 函数返回的结果创建一个 list. 结果的顺序与原集合中的元素顺序相同. 如果变换时还需要元素下标参数, 请使用 mapIndexed() 函数.
1 | val numbers = setOf(1, 2, 3) |
如果对某些元素变换的结果是 null, 你可以将这些 null 值从结果集合中过滤掉, 方法是使用 mapNotNull() 函数代替 map() 函数, 或者相应的使用 mapIndexedNotNull() 函数代替 mapIndexed() 函数.
1 | val numbers = setOf(1, 2, 3) |
其他 mapKeys()要对键(key)进行指定的变换,mapValues()要变换值(value)
合并(Zipping)
合并(Zipping) 变换, 将两个集合中相同位置的元素合并为 pair. Kotlin 标准库中, 这个操作使用 zip() 扩展函数实现.
可以对一个集合或数组调用 zip() 函数, 参数是另一个集合(或数组), 返回值是 Pair 对象构成的 List. 接受者对象集合中的元素, 将成为这些 pair 中的第一个元素.
如果两个集合的大小不同, zip() 返回的结果只包含较小的那个集合大小; 较大的集合中的末尾元素不会出现在结果中.
zip() 也可以使用中缀形式调用, 也就是 a zip b.
1 | val colors = listOf("red", "brown", "grey") |
如果已有 Pair 构成的 List, 你可以做相反的变换 – 分离(unzipping) – 它会通过这些 pair 创建两个 list:
第一个 list 包含原 List 的每个 Pair 中的第一个元素.
第二个 list 包含 Pair 中的第二个元素.
要分离 pair 构成的 list, 请使用 unzip() 函数.
1 | val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4) |
关联(Association)
关联(Association) 变换, 可以使用指定集合的元素以及与各元素对应的值创建 map. 在不同的关联类型中, 原集合的元素可以是结果 map 中的键(key), 也可以是值(value).
基本的关联函数 associateWith() 会创建一个 Map, 原集合的元素成为它的键(key), 值(value)由一个变换函数通过这些元素计算得到. 如果两个元素相等, 那么只有后一个会保留在 map 中.
1 | val numbers = listOf("one", "two", "three", "four") |
如果要把集合元素变换为 map 中的值(value), 请使用 associateBy() 函数. 它的参数是一个函数, 这个函数根据元素值返回一个键(key). 如果两个元素的 Key 相等, 那么只有后一个会保留在 map 中.
调用 associateBy() 时, 也可以指定一个值变换函数.
1 | val numbers = listOf("one", "two", "three", "four") |
构建 map 的另一种方法是 associate() 函数, 它根据集合元素通过某种方法同时产生键(key)和值(value). 这个函数的参数是一个 lambda 函数, lambda 函数返回一个 Pair: 其中包含对应的 map 条目(entry) 的键(key)和值(value).
注意, associate() 产生的是临时存在(short-living)的 Pair 对象, 可能会影响性能. 因此, 只有性能问题不是很关键, 或者它比其他方式更合理的情况下, 才应该使用 associate() 函数.
后一种情况的例子是, 如果需要从集合元素同时产生键(key)和对应的值(value), 那么就应该使用 associate() 函数了.
1 | val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell") |
扁平化(Flattening)
标准库提供了对嵌套集合(nested collection)的元素进行扁平化访问(flat access)的函数, 对于嵌套集合(nested collection)的操作非常便利.
第一个函数是 flatten(). 可以对一个集合的集合调用这个函数, 比如, Set 构成的 List. 这个函数返回单个 List, 其中包含嵌套集合中的所有元素.
1 | val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2)) |
另一个函数 – flatMap() 提供了一种灵活的方式来处理嵌套集合. 它的参数是一个函数, 负责将集合中的一个元素变换为另一个集合. flatMap() 的结果返回单个 list, 其中包括对原集合各个元素调用变换函数后返回的集合中的所有元素. 因此, flatMap() 的行为等于调用 map() (映射(Mapping)的结果是一个集合) 之后再调用 flatten().
1 | val containers = listOf( |
字符串表达(String representation)
如果你需要将集合内容表达为人类可读的格式, 请使用将集合转换为字符串的函数: joinToString() 和 joinTo().
joinToString() 根据指定的参数, 从集合元素创建单个 String. joinTo() 执行同样的功能, 但把结果添加到指定的 Appendable 对象中.
如果使用默认参数调用这些函数, 返回的结果与对集合调用 toString() 函数类似: 由各个元素的字符串表达组成的 String, 元素之间以逗号加空格分隔.
1 | val numbers = listOf("one", "two", "three", "four") |
如果要创建自定义的字符串表达, 可以指定函数参数 separator, prefix, 以及 postfix. 结果字符串以 prefix 开始, 以 postfix 结尾. separator 会出现在每个元素之后, 最后一个元素除外.
1 | val numbers = listOf("one", "two", "three", "four") |
对比较大的集合, 你可能需要指定 limit – 结果中包含的最大元素个数. 如果集合大小超过 limit 值, 所有超过的元素会被替换为 truncated 参数指定的值.
1 | 对比较大的集合, 你可能需要指定 limit – 结果中包含的最大元素个数. 如果集合大小超过 limit 值, 所有超过的元素会被替换为 truncated 参数指定的值. |
最后, 如果要控制集合元素本身的字符串表达, 可以指定一个 transform 函数.
1 | val numbers = listOf("one", "two", "three", "four") |
过滤(Filtering)集合
filter()
filterNot()
1 | val numbers = listOf("one", "two", "three", "four") |
1 | val numbers = listOf("one", "two", "three", "four") |
加法(Plus) 和 减法(Minus) 操作符
在 Kotlin 中, 也为集合定义了 加法(Plus) (+) 和 减法(Minus) (-) 操作符. 这些操作符使用一个集合作为第一个操作数; 第二个操作数可以是单个元素, 也可以是另一个集合. 返回值是一个新的只读集合:
加法(Plus) 的返回值包含原来集合中的元素 和 第二个操作数的元素.
减法(Minus) 的返回值包含原来集合中的元素, 但要 除去 第二个操作数的元素. 如果第二个操作数是单个元素, 减法(Minus) 只删除原来的集合中 第一次 出现的这个元素; 如果第二个操作数是一个集合, 那么原来的集合中 所有 出现的这些元素都会被删除.
1 | val numbers = listOf("one", "two", "three", "four") |
分组(Grouping)
Kotlin 标准库提供了扩展函数, 用于对集合中的元素进行分组操作. 最基本的函数是 groupBy(), 它接受一个 lambda 函数为参数, 返回结果是一个 Map. 在这个 map 中, 每个键(key)是 lambda 函数的一个返回结果, 与键(key)对应的值(value) 是一个 List, 其中包含返回这个结果的所有元素. 这个函数的用途, 举例来说, 我们可以对一个 String 组成的 list, 按字符串的首字母进行分组.
调用 groupBy() 函数时, 也可以使用另一个 lambda 函数作为第二个参数 – 这个函数负责对值进行变换. 象这样使用两个 lambda 函数调用 groupBy()时, 结果 map 中, 第一个参数(keySelector lambda 函数)负责生成键(key), 它对应的值(value) 则是由第二个参数(值转换 lambda 函数)产生的结果组成的 list, 而不是集合中原来元素组成的 list.
1 | val numbers = listOf("one", "two", "three", "four", "five") |
1 |