List es el tipo más popular de colección incorporada en Kotlin. El acceso de índice a los elementos de las listas proporciona un poderoso conjunto de operaciones para las listas.

Recuperando elementos por índice

Las listas admiten todas las operaciones comunes para la recuperación de elementos: elementAt(), first(), last()y otros enumerados en Recuperación de elementos individuales. Lo que es específico para las listas es el acceso de índice a los elementos, por lo que la forma más sencilla de leer un elemento es recuperarlo por índice. Eso se hace con el get() función con el índice pasado en el argumento o la taquigrafía [index] sintaxis.

Si el tamaño de la lista es menor que el índice especificado, se lanza una excepción. Hay otras dos funciones que lo ayudan a evitar tales excepciones:

  • getOrElse() le permite proporcionar la función para calcular el valor predeterminado que se devolverá si el índice no está presente en la colección.
  • getOrNull() devoluciones null como valor predeterminado.
funmain()//sampleStartval numbers =listOf(1,2,3,4)println(numbers.get(0))println(numbers[0])//numbers.get(5)                         // exception!println(numbers.getOrNull(5))// nullprintln(numbers.getOrElse(5,it))// 5//sampleEnd

Recuperando partes de la lista

Además de las operaciones comunes para recuperar piezas de colección, las listas proporcionan la subList() función que devuelve una vista del rango de elementos especificado como una lista. Así, si un elemento de la colección original cambia, también cambia en las sublistas creadas previamente y viceversa.

funmain()//sampleStartval numbers =(0..13).toList()println(numbers.subList(3,6))//sampleEnd

Encontrar posiciones de elementos

Búsqueda lineal

En cualquier lista, puede encontrar la posición de un elemento usando las funciones indexOf() y lastIndexOf(). Devuelven la primera y la última posición de un elemento igual al argumento dado en la lista. Si no hay tales elementos, ambas funciones devuelven -1.

funmain()//sampleStartval numbers =listOf(1,2,3,4,2,5)println(numbers.indexOf(2))println(numbers.lastIndexOf(2))//sampleEnd

También hay un par de funciones que toman un predicado y buscan elementos que coincidan con él:

  • indexOfFirst() devuelve el índice de la primera elemento que coincide con el predicado o -1 si no existen tales elementos.
  • indexOfLast() devuelve el índice de la última elemento que coincide con el predicado o -1 si no existen tales elementos.
funmain()//sampleStartval numbers =mutableListOf(1,2,3,4)println(numbers.indexOfFirst it >2)println(numbers.indexOfLast it %2==1)//sampleEnd

Búsqueda binaria en listas ordenadas

Hay una forma más de buscar elementos en listas: búsqueda binaria. Funciona significativamente más rápido que otras funciones de búsqueda integradas, pero requiere que la lista esté ordenada en orden ascendente según un orden determinado: natural u otro previsto en el parámetro de función. De lo contrario, el resultado no está definido.

Para buscar un elemento en una lista ordenada, llame al binarySearch() función pasando el valor como argumento. Si tal elemento existe, la función devuelve su índice; de lo contrario, vuelve (-insertionPoint - 1) dónde insertionPoint es el índice donde se debe insertar este elemento para que la lista permanezca ordenada. Si hay más de un elemento con el valor dado, la búsqueda puede devolver cualquiera de sus índices.

También puede especificar un rango de índice para buscar: en este caso, la función busca solo entre dos índices proporcionados.

funmain()//sampleStartval numbers =mutableListOf("one","two","three","four")
    numbers.sort()println(numbers)println(numbers.binarySearch("two"))// 3println(numbers.binarySearch("z"))// -5println(numbers.binarySearch("two",0,2))// -3//sampleEnd

Búsqueda binaria del comparador

Cuando los elementos de la lista no lo son Comparable, debe proporcionar un Comparator para usar en la búsqueda binaria. La lista debe ordenarse en orden ascendente de acuerdo con este Comparator. Echemos un vistazo a un ejemplo:

dataclassProduct(val name: String,val price: Double)funmain()//sampleStartval productList =listOf(Product("WebStorm",49.0),Product("AppCode",99.0),Product("DotTrace",129.0),Product("ReSharper",149.0))println(productList.binarySearch(Product("AppCode",99.0), compareBy<Product> it.price .thenBy it.name ))//sampleEnd

Aquí hay una lista de Product instancias que no lo son Comparable y un Comparator que define el pedido: producto p1 precede al producto p2 si p1El precio es menor que p2precio. Entonces, al tener una lista ordenada de manera ascendente de acuerdo con este orden, usamos binarySearch() para encontrar el índice del especificado Product.

Los comparadores personalizados también son útiles cuando una lista utiliza un orden diferente al natural, por ejemplo, un orden que no distingue entre mayúsculas y minúsculas para String elementos.

funmain()//sampleStartval colors =listOf("Blue","green","ORANGE","Red","yellow")println(colors.binarySearch("RED", String.CASE_INSENSITIVE_ORDER))// 3//sampleEnd

Comparación de búsqueda binaria

Búsqueda binaria con comparación La función le permite buscar elementos sin proporcionar valores de búsqueda explícitos. En su lugar, se necesitan elementos de mapeo de funciones de comparación para Int valores y busca el elemento donde la función devuelve cero. La lista debe estar ordenada en orden ascendente de acuerdo con la función proporcionada; en otras palabras, los valores de retorno de la comparación deben crecer de un elemento de la lista al siguiente.

import kotlin.math.sign
//sampleStartdataclassProduct(val name: String,val price: Double)funpriceComparison(product: Product, price: Double)=sign(product.price - price).toInt()funmain()val productList =listOf(Product("WebStorm",49.0),Product("AppCode",99.0),Product("DotTrace",129.0),Product("ReSharper",149.0))println(productList.binarySearchpriceComparison(it,99.0))//sampleEnd

Tanto el comparador como la búsqueda binaria de comparación se pueden realizar también para rangos de lista.

Lista de operaciones de escritura

Además de las operaciones de modificación de la colección descritas en Operaciones de escritura de la colección, las listas mutables admiten operaciones de escritura específicas. Estas operaciones utilizan el índice para acceder a elementos para ampliar las capacidades de modificación de la lista.

Añadiendo

Para agregar elementos a una posición específica en una lista, use add() y addAll() proporcionando la posición para la inserción del elemento como argumento adicional. Todos los elementos que vienen después de la posición se desplazan hacia la derecha.

funmain()//sampleStartval numbers =mutableListOf("one","five","six")
    numbers.add(1,"two")
    numbers.addAll(2,listOf("three","four"))println(numbers)//sampleEnd

Actualizando

Las listas también ofrecen una función para reemplazar un elemento en una posición determinada: set() y su forma de operador []. set() no cambia los índices de otros elementos.

funmain()//sampleStartval numbers =mutableListOf("one","five","three")
    numbers[1]="two"println(numbers)//sampleEnd

fill() simplemente reemplaza todos los elementos de la colección con el valor especificado.

funmain()//sampleStartval numbers =mutableListOf(1,2,3,4)
    numbers.fill(3)println(numbers)//sampleEnd

Eliminando

Para eliminar un elemento en una posición específica de una lista, use el removeAt() función que proporciona la posición como argumento. Todos los índices de elementos que vienen después del elemento que se elimina disminuirán en uno.

funmain()//sampleStartval numbers =mutableListOf(1,2,3,4,3)    
    numbers.removeAt(1)println(numbers)//sampleEnd

Para eliminar el primer y el último elemento, existen prácticos atajos removeFirst() y removeLast(). Tenga en cuenta que en las listas vacías, lanzan una excepción. Para recibir null en su lugar, usa removeFirstOrNull() y removeLastOrNull()

funmain()//sampleStartval numbers =mutableListOf(1,2,3,4,3)    
    numbers.removeFirst()
    numbers.removeLast()println(numbers)val empty = mutableListOf<Int>()// empty.removeFirst() // NoSuchElementException: List is empty.
    empty.removeFirstOrNull()//null//sampleEnd

Clasificación

En Orden de colección, describimos operaciones que recuperan elementos de colección en órdenes específicas. Para listas mutables, la biblioteca estándar ofrece funciones de extensión similares que realizan las mismas operaciones de pedido en su lugar. Cuando aplica una operación de este tipo a una instancia de lista, cambia el orden de los elementos en esa instancia exacta.

Las funciones de clasificación in situ tienen nombres similares a las funciones que se aplican a las listas de solo lectura, pero sin la ed/d sufijo:

  • sort* en lugar de sorted* en los nombres de todas las funciones de clasificación: sort(), sortDescending(), sortBy(), etcétera.
  • shuffle() en lugar de shuffled().
  • reverse() en lugar de reversed().

asReversed() llamado en una lista mutable devuelve otra lista mutable que es una vista inversa de la lista original. Los cambios en esa vista se reflejan en la lista original. El siguiente ejemplo muestra funciones de clasificación para listas mutables:

funmain()//sampleStartval numbers =mutableListOf("one","two","three","four")

    numbers.sort()println("Sort into ascending: $numbers")
    numbers.sortDescending()println("Sort into descending: $numbers")

    numbers.sortBy it.length println("Sort into ascending by length: $numbers")
    numbers.sortByDescending it.last()println("Sort into descending by the last letter: $numbers")
    
    numbers.sortWith(compareBy<String> it.length .thenBy it )println("Sort by Comparator: $numbers")

    numbers.shuffle()println("Shuffle: $numbers")

    numbers.reverse()println("Reverse: $numbers")//sampleEnd