List 相关操作

    List 支持按索引取元素的所有常用操作: elementAt()first()last() 与中列出的其他操作。 List 的特点是能通过索引访问特定元素,因此读取元素的最简单方法是按索引检索它。 这是通过 get() 函数或简写语法 [index] 来传递索引参数完成的。

    如果 List 长度小于指定的索引,则抛出异常。 另外,还有两个函数能避免此类异常:

    • 提供用于计算默认值的函数,如果集合中不存在索引,则返回默认值。
    • getOrNull() 返回 null 作为默认值。

    除了中常用的操作, List 还提供 subList() 该函数将指定元素范围的视图作为列表返回。 因此,如果原始集合的元素发生变化,则它在先前创建的子列表中也会发生变化,反之亦然。

    1. fun main() {
    2. //sampleStart
    3. val numbers = (0..13).toList()
    4. println(numbers.subList(3, 6))
    5. //sampleEnd
    6. }

    在任何列表中,都可以使用 或 lastIndexOf() 函数找到元素的位置。 它们返回与列表中给定参数相等的元素的第一个或最后一个位置。 如果没有这样的元素,则两个函数均返回 -1

    1. fun main() {
    2. //sampleStart
    3. val numbers = listOf(1, 2, 3, 4, 2, 5)
    4. println(numbers.indexOf(2))
    5. println(numbers.lastIndexOf(2))
    6. //sampleEnd
    7. }

    还有一对函数接受谓词并搜索与之匹配的元素:

    • 返回与谓词匹配的第一个元素的索引,如果没有此类元素,则返回 -1
    • indexOfLast() 返回与谓词匹配的最后一个元素的索引,如果没有此类元素,则返回 -1
    1. fun main() {
    2. //sampleStart
    3. val numbers = mutableListOf(1, 2, 3, 4)
    4. println(numbers.indexOfFirst { it > 2})
    5. println(numbers.indexOfLast { it % 2 == 1})
    6. //sampleEnd
    7. }

    在有序列表中二分查找

    还有另一种搜索列表中元素的方法——。 它的工作速度明显快于其他内置搜索功能,但要求该列表按照一定的顺序(自然排序或函数参数中提供的另一种排序)按升序排序过。 否则,结果是不确定的。

    还可以指定要搜索的索引区间:在这种情况下,该函数仅在两个提供的索引之间搜索。

    Comparator 二分搜索

    如果列表元素不是 Comparable,则应提供一个用于二分搜索的 。 该列表必须根据此 Comparator 以升序排序。来看一个例子:

    1. data class Product(val name: String, val price: Double)
    2. fun main() {
    3. val productList = listOf(
    4. Product("WebStorm", 49.0),
    5. Product("AppCode", 99.0),
    6. Product("DotTrace", 129.0),
    7. Product("ReSharper", 149.0))
    8. println(productList.binarySearch(Product("AppCode", 99.0), compareBy<Product> { it.price }.thenBy { it.name }))
    9. //sampleEnd
    10. }

    这是一个不可排序Product 实例列表,以及一个定义排序的 Comparator:如果 p1 的价格小于 p2 的价格,则产品 p1 在产品 p2 之前。 因此,按照此顺序对列表进行升序排序后,使用 binarySearch() 查找指定的 Product的索引。

    当列表使用与自然排序不同的顺序时(例如,对 String 元素不区分大小写的顺序),自定义 Comparator 也很方便。

    1. fun main() {
    2. //sampleStart
    3. val colors = listOf("Blue", "green", "ORANGE", "Red", "yellow")
    4. println(colors.binarySearch("RED", String.CASE_INSENSITIVE_ORDER)) // 3
    5. //sampleEnd
    6. }

    比较函数二分搜索

    使用 比较 函数的二分搜索无需提供明确的搜索值即可查找元素。 取而代之的是,它使用一个比较函数将元素映射到 Int 值,并搜索函数返回 0 的元素。 该列表必须根据提供的函数以升序排序;换句话说,比较的返回值必须从一个列表元素增长到下一个列表元素。

    1. import kotlin.math.sign
    2. //sampleStart
    3. data class Product(val name: String, val price: Double)
    4. fun priceComparison(product: Product, price: Double) = sign(product.price - price).toInt()
    5. fun main() {
    6. val productList = listOf(
    7. Product("WebStorm", 49.0),
    8. Product("AppCode", 99.0),
    9. Product("DotTrace", 129.0),
    10. Product("ReSharper", 149.0))
    11. println(productList.binarySearch { priceComparison(it, 99.0) })
    12. }
    13. //sampleEnd

    Comparator 与比较函数二分搜索都可以针对列表区间执行。

    要将元素添加到列表中的特定位置,请使用 add() 或 并提供元素插入的位置作为附加参数。 位置之后的所有元素都将向右移动。

    更新

    列表还提供了在指定位置替换元素的函数——set() 及其操作符形式 []set() 不会更改其他元素的索引。

    1. fun main() {
    2. //sampleStart
    3. val numbers = mutableListOf("one", "five", "three")
    4. numbers[1] = "two"
    5. println(numbers)
    6. //sampleEnd
    7. }

    简单地将所有集合元素的值替换为指定值。

    1. fun main() {
    2. numbers.fill(3)
    3. println(numbers)
    4. //sampleEnd
    5. }

    要从列表中删除指定位置的元素,请使用 removeAt() 函数,并将位置作为参数。 在元素被删除之后出现的所有元素索引将减 1。

    1. fun main() {
    2. //sampleStart
    3. val numbers = mutableListOf(1, 2, 3, 4, 3)
    4. numbers.removeAt(1)
    5. println(numbers)
    6. //sampleEnd
    7. }

    For removing the first and the last element, there are handy shortcuts and removeLast(). Note that on empty lists, they throw an exception. To receive null instead, use and removeLastOrNull()

    排序

    在中,描述了按特定顺序检索集合元素的操作。 对于可变列表,标准库中提供了类似的扩展函数,这些扩展函数可以执行相同的排序操作。 将此类操作应用于列表实例时,它将更改指定实例中元素的顺序。

    • sort* 在所有排序函数的名称中代替 sorted*sort()、、sortBy() 等等。
    • 代替 shuffled()
    • reverse() 代替 reversed()

    在可变列表上调用会返回另一个可变列表,该列表是原始列表的反向视图。在该视图中的更改将反映在原始列表中。 以下示例展示了可变列表的排序函数:

    1. fun main() {
    2. //sampleStart
    3. val numbers = mutableListOf("one", "two", "three", "four")
    4. numbers.sort()
    5. println("Sort into ascending: $numbers")
    6. numbers.sortDescending()
    7. println("Sort into descending: $numbers")
    8. numbers.sortBy { it.length }
    9. println("Sort into ascending by length: $numbers")
    10. numbers.sortByDescending { it.last() }
    11. println("Sort into descending by the last letter: $numbers")
    12. numbers.sortWith(compareBy<String> { it.length }.thenBy { it })
    13. println("Sort by Comparator: $numbers")
    14. numbers.shuffle()
    15. println("Shuffle: $numbers")
    16. numbers.reverse()
    17. println("Reverse: $numbers")
    18. //sampleEnd