Kotlin - Llista

Una llista és un conjunt d'elements agrupats un a continuació de l'altre.

Introducció

Una List és una seqüència de valors que tenen tots el mateix tipus de dada.

listOf

Una llista és un tipus genèric que s’ha de concretar amb el tipus que tenen els elements de la llista.

Per exemple, a continuació tens una llista de valors de tipus List<Int>:

val list: List<Int> = listOf(1, 2, 3)

La funció listOf() rep els elements com a paràmetres i els retorna dins una List

for

Pots recorrer tots els elements de la llista amb un bucle for:

val numbers = listOf(4, 8, 2)
for (number in numbers) {
    println(number)
}

Pots veure que:

  • Utilitzes la paraula clau for seguida d’un parell de parèntesis.

  • Dins dels parèntesis, inclous un nom de variable, seguit de la paraula clau in, i després el nom de la llista.

  • Després del parèntesi de tancament, ve un parell de claus d’obertura i tancament {}, on inclous el codi que vols executar per a cada element de la llista. Això és el cos del bucle. Cada vegada que s’executa aquest codi s’anomena una iteració.

  • La variable abans de la paraula clau in no es declara amb val ni var; s’assumeix que és de només lectura. La pots anomenar com vulguis.

  • Si a una llista li poses un nom en plural, com animals, és comú anomenar la variable amb el singular, com animal. També és habitual anomenar-la item o element.

  • Aquesta variable s’utilitza com a variable temporal corresponent a l’element actual de la llista i es pot fer servir dins de les claus.

A continuació tens un codi que suma tots els elements de la llista numbers:

val numbers = listOf(4, 8, 2)

var sum = 0
for (number in numbers) {
    sum += number
}

require(sum == 14) { "Sum should be 14" }
Activitat

A continuació tens una llista d’animals.

Completa el bucle for per tal que busqui si la llista té una “Dog”:

val animals = listOf("Cat", "Dog", "Cow")

var found = false
for (animal in animals) {
    // ...
}

Index

Hem explicat que una List conté múltiples valors anomenats elements, o, de vegades, ítems.

71600339414

Els elements d’una List estan ordenats i pots accedir amb un índex.

71600339414
012345

Què és un índex? Un índex és un nombre enter que correspon a un element de la llista.

Un índex indica la distància d’un ítem respecte de l’element inicial d’una llista.

Això s’anomena indexació des de zero. El primer element de la llista és a l’índex 0, el segon element és a l’índex 1, perquè és a un lloc del primer element, i així successivament.

get

Pots accedir a un element en un índex específic d’una List utilitzant el mètode get de subindex:

val animals = listOf("Cat", "Dog", "Cow", "Chicken")
require(animals[0] == "Cat")

O bé amb la sintaxi abreujada [índex]:

val animals = listOf("Cat", "Dog", "Cow", "Chicken")
require(animals[2] == "Cow")

Una llista de 4 elements només té 4 índexs: 0, 1, 2, 3.

Si intentes accedir amb un índex que no existeix …

val animals = listOf("Cat", "Dog", "Cow", "Chicken")
animals[10]

Obtens un error:

ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 4

Per evitar que això pugui passar, si no estàs completament segur, utilitza una d’aquestes funcions:

  • getOrElse() et permet proporcionar una funció per calcular el valor per defecte a retornar si l’índex no és present a la col·lecció.

  • getOrNull() retorna null com a valor per defecte.

val animals = listOf("Cat", "Dog", "Cow", "Chicken")

require(animals.getOrNull(3) == "Chicken")
require(animals.getOrNull(10) == null)

require(animals.getOrElse(3) { "Unknown" } == "Chicken")
require(animals.getOrElse(10) { "Unknown" } == "Unknown")

=

Pots actualitzar elements existents amb la sintaxi de subíndex:

val animals = mutableListOf("Cat", "Dog", "Cow", "Chicken")

animals[1] ="Tiger"
require(animals[1] == "Tiger")
require(animals[2] == "Cow")

indexOf

A més d’obtenir un element pel seu índex, també pots cercar l’índex d’un element específic amb el mètode indexOf().

El mètode indexOf() busca a la llista l’element donat (passat com a argument) i retorna l’índex de la primera ocurrència d’aquell element.

val animals = listOf("Cat", "Dog", "Cow", "Chicken")
require(animals.indexOf("Chicken") == 3)

Si l’element no és a la llista, retorna -1.

val animals = listOf("Cat", "Dog", "Cow", "Chicken")

require(animals.indexOf("Fox") == -1)

size

List té una propietat size per obtenir el nombre d’elements de la llista.

val animals = listOf("Cat", "Dog", "Cow", "Chicken")
require(animals.size == 4)

MutableList

El tipus MutableList amplia el tipus List definint mètodes per modificar una llista, com afegir i eliminar elements.

Si vols poder afegir elements sovint a una llista, has de cridar específicament la funció mutableListOf(), en lloc de listOf(), quan creïs una llista de la qual vulguis afegir i eliminar elements.

add

Hi ha dues versions de la funció add().

La primera add() té un únic paràmetre del tipus d’element de la llista i l’afegeix al final de la llista.

val animals = mutableListOf("Cat", "Dog", "Cow", "Chicken")

animals.add("Tiger")
require(animals[4] == "Tiger")

L’altra versió d’add() té dos paràmetres:

  • El primer paràmetre correspon a l’índex on s’ha d’inserir el nou element.
  • El segon paràmetre és l’element que s’afegeix a la llista.
val animals = mutableListOf("Cat", "Dog", "Cow", "Chicken")

animals.add(1,"Tiger")
require(animals[1] == "Tiger")
require(animals[2] == "Dog")

remove

Pots eliminar elements d’una llista utilitzant el mètode remove().

El mètode remove() pren un únic paràmetre, que és l’element que s’ha d’eliminar.

val animals = mutableListOf("Cat", "Dog", "Cow", "Chicken")

animals.remove("Dog")
require(animals.indexOf("Dog") == -1)

Tipus específic

Molts cops les llistes són paràmetres de funcions o el resultat de funcions.

fun sum(list: List<Int>): Int {
    var result = 0
    for (item in list) {
        result += item
    }
    return result
}

Això vol dir que tots els elements de la llista són del tipus específic (en aquest cas Int), i només pots aplicar operacions específiques a aquest tipus als seus elements..

A continuació tens una llista de valors de tipus List<String>:

val animals = listOf("Cat", "Dog", "Cow")
animals[0] == 3

Si executes el codi anterior, obtens un error:

Operator '==' cannot be applied to 'String' and 'Int'.

També pots tenir una llista que permet qualsevol tipus:

val list: List<Any> = listOf(1, "cat", 2.3)

El tipus Any vol dir qualsevol tipus, i es poden fer poques operacions amb aquests tipus.

Els puc comparar:

val animals: List<Any> = listOf(1, "Dog", 3.0)
require(animals[0] == 1)

Però no pots fer operacions com + o *

val animals: List<Any> = listOf(1, "Dog", 3.0)
animals[0] + 4

Encara que alguns siguin números:

Unresolved reference 'plus' for operator '+'.

TODO