Listas en Kotlin
En el capítulo anterior hablamos sobre los arrays o arreglos y vimos todo el potencial que tenía, pero uno de los mayores inconvenientes era la limitación al definirlos, puesto que teníamos que saber de ante mano el tamaño de dicho array.
Tipos de listas
Las colecciones se pueden clasificar en dos grandes grupos, las mutables e inmutables. Es decir, las que se pueden editar (mutables) y las que son solo de lectura (inmutable).
Listas inmutables
La declaración de una lista inmutable sería así.
val readOnly: List<String> = listOf("Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo")
Existen varias funciones útiles para trabajar con ellas.
val readOnly: List<String> = listOf("Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado", "Domingo") readOnly.size //Muestra el tamaño de la lista readOnly.get(3) //Devuelve el valor de la posición 3 readOnly.first() //Devuelve el primer valor readOnly.last() //Devuelve el último valor println(readOnly) //[Lunes, Martes, Miércoles, Jueves, Viernes, Sábado, Domingo]
Como pueden ver podemos trabajar completamente con ellas, a excepción de añadir más elementos.
También podemos filtrar usando el patrón iterator, que es un mecanismo para acceder a los elementos de la lista, por ejemplo .first() o .last()
val a = readOnly.filter { it == "Lunes" || it == "Juernes" }
El .filter nos permite filtrar en la lista a través de una o varias condiciones que pongamos. Para ello llamamos a it (iterator) y buscaremos en la lista, si contiene la palabra «Lunes» o «Juernes«. En este caso solo pintará «Lunes«.
Listas mutables
Ahora nos toca hablar de las más interesantes, las listas mutables, que poseen todo lo anterior, pero también nos da la posibilidad de ir rellenando la lista a medida que lo necesitemos, el único inconveniente es que más ineficiente con la memoria.
var mutableList: MutableList<String> = mutableListOf("Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado") println(readOnly) //[Lunes, Martes, Miércoles, Jueves, Viernes, Sábado] mutableList.add("domingo")
La definición es muy similar, a través de la función mutableListOf. Ahora si os fijáis he añadido de lunes a sábado que será lo que pintará, luego, usando mutableList.add he añadido el domingo.
Por defecto los valores se irán añadiendo en la última posición, pero podemos añadir el índice en el que queramos escribir nuestro valor.
mutableList.add(0, "Semana: ")
Con esto, si pintásemos la lista nos mostraría lo siguiente.
[Semana: , Lunes, Martes, Miércoles, Jueves, Viernes, Sábado, domingo]
Ahora tenemos que tener cuidado con una lista mutable por el simple hecho de que podría estar vacía o contener un null. Un null es un valor nulo en una de sus posiciones, que, si acedemos a él e intentamos operar, la aplicación se romperá, nos saltará un crash. Para ello, tenemos algunas funciones que nos permitirá trabajar como una lista inmutable, pero con seguridad.
var mutableList: MutableList<String> = mutableListOf() mutableList.none() //Nos devuelve un true si está vacía la lista mutableList.firstOrNull() //Nos devolverá el primer campo, y si no hay, un null. mutableList.elementAtOrNull(2) //El elemento del índice 2, si no hay, devolverá un null mutableList.lastOrNull() //Último valor de la lista o null
En este ejemplo he instanciado una lista sin valor alguno, por lo que está vacía. Con todos esos métodos recuperaremos un null (menos el primero que dará true) y la aplicación seguirá corriendo, si por le contrario hubiera puesto un .first() nos hubiese pasado lo siguiente.
Debemos de tener mucho cuidado a la hora de trabajar con datos que puedan mutar.
Recorriendo listas
Igual que hicimos en el capítulo de las arrays, aquí también tenemos formas (muy similares) para recorrer las listas.
Esta sería la forma más sencilla, y nos devolvería el contenido de cada uno de los valores de la lista.
for (item in mutableList) { print(item) }
Si necesitamos saber también la posición de cada uno de los valores podemos usar la función .withIndex que nos permite generar 2 variables, la primera será la posición y la segunda el contenido.
for ((indice, item) in mutableList.withIndex()) { println("La posición $indice contiene $item") }
Para el último ejemplo, usaremos .forEach, una función que hará que por cada posición haga una cosa, por ejemplo pintar el valor como el for anterior. A diferencia de ellos, no tenemos una variable con el contenido (véase índice e item) sino que accedemos a él con el iterator, en este caso simplemente habría que poner it.
En este ejemplo imaginemos que queremos añadir a los días de la semana dos puntos «:» así que vamos a crear una nueva lista (mutable) e iremos rellenando la lista a través del forEach.
val mutableList: MutableList<String> = mutableListOf("Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado") val newListEmpty: MutableList<String> = mutableListOf() mutableList.forEach { newListEmpty.add(it+":") } print(newListEmpty)
Continúa con el curso: Capítulo 11 – Configurando Android Studio para Kotlin
En esta mañana me he leido los 10 capitulos y te agradezco por ellos son geniales. Tienes alma de maestro en ayudar a todos los hambrientos de conocimiento (me incluyo) Gracias.
Cuando subes mas capitulos????
Me alegra mucho leer este tipo de comentarios. Aquí tienes el índice de todos los capítulos ( https://cursokotlin.com/curso-programacion-kotlin-android/ ) , ahora vamos por el 16, el 17 espero sacarlo esta semana (es bastante amplio), persistencia de datos con Room, muy interesante y útil. En la página de Facebook voy publicando todos los capítulos nuevos por si quieres dejar un like 😉
Saludos!
El día de hoy 18 de mayo de 2018 me he leido los 10 capitulos, y segui buscando y encontre que que existen capitulos del 11 al 17 con Android Studio, pero mi pregunta es ¿tendras más capitulos del lenguaje puro?, son muy buenos y me gustaria continuar aprendiendo.
La idea es seguir enfocando el proyecto a Android, de todos modos en cada uno de los capítulos suelo explicar algo de sintaxis del lenguaje.
Un saludo
Hola Aris,
No entiendo por qué lo siguiente funciona.
for ((indice, item) in mutableList.withIndex()) {
println(«La posición $indice contiene $item»)
}
«indice» y «item» son nombres que te estás inventando tu no? Podrías llamarles index y cosa por ejemplo.
Imagino que independientemente del nombre que le des, la primera siempre sera para indice y la segunda para el valor, y no aceptará más de dos parametros?
Exacto @Marcos, los nombres los puedes poner a tu gusto. ¿Qué es lo que no funciona o que error tienes? Entiendo que «mutableList» es una lista que tú previamente has creado no?
Saludos
Hola Gracias por responder tan rápido.
Lo que ocurría es que no acababa de entender si el primer argumento correspondía siempre al indice, y el segundo al valor, entonces. Ya lo tengo claro.
En java no existen este tipo de for o al menos no lo s he usado, hay que ir adaptándonos ^^
Saludos!
Adaptarse o morir haha. Cualquier otra duda por aquí ando 🙂
muchas gracias…
en serio me ha sido muy útil
aprendí muchísimo y me ayudo en algunas dudas que tenia
Hola Aris! Muchas gracias por tu cursillo, con el ayudas mucho a la comunidad.
Una cosa que quizas no haya entendido bien el concepto… En las listas mutables las declaras como «val» ¿no se deberian declarar como «var»?
Saludos!
Tienes toda la razón, fallo mío 🙂
Muchas gracias por reportar el error!
Hola Aris.
Excelente tutorial, muchas gracias 🙂
Una duda en relación con esto mismo: el siguiente código en Android Studio me muestra como sugerencia que declare mutableList como val porque «la variable no se modifica y puede ser declarada inmutable»:
var mutableList: MutableList = mutableListOf(«Lunes», «Martes», «Miércoles», «Jueves», «Viernes», «Sábado»)
println(mutableList) //[Lunes, Martes, Miércoles, Jueves, Viernes, Sábado]
mutableList.add(«domingo»)
Pero sí que la estoy modificando, estoy agregando el elemento «domingo» al final de la lista.
Cambiando «var» por «val» el código sigue funcionando. ¿Cómo es posible? Aquí hay algo que se me escapa…
Un saludo.
Buenas, es normal confundirse con esto. Estás creando una única lista, esa lista es mutable por lo que puedes añadir parámetros, pero es val porque NUNCA cambias la referencia de tu lista. Me explico:
var mutableList: MutableList = mutableListOf(“Lunes”, “Martes”, “Miércoles”, “Jueves”, “Viernes”, “Sábado”)
var mutableList2: MutableList = mutableListOf(“a”, “b”, “c”, “d”, “e”, “f”)
println(mutableList) //[Lunes, Martes, Miércoles, Jueves, Viernes, Sábado]
mutableList.add(“domingo”)
mutableList = mutableList2 //Esto es lo que no podríamos hacer.
Un saludo
tengo una duda, no me deja agregar reconoce la palabra clave «add»
fun main(args: Array){
val listaInm:List =listOf(1,2,3,4,5,6,7,8,9)
for(entero in listaInm){
print(entero)
}
var listaMut:List =listOf(1,2,3,4,5,6,7,8,9)
listaMut.add(3)//me aparece «Unresolved reference: add»
}
Buenas, el problema es que estás haciendo una lista inmutable. Para hacerla mutable tendrías que hacer mutableListOf en vez de listOf.
Ej:
var listaMut = mutableListOf(1,2,3,4,5,6,7,8,9)
listaMut.add(3)
Hola, no entiendo qué hace exactamente este trozo de código:
mutableList.forEach {
newListEmpty.add(it+»:»)
}
print(newListEmpty)
Lo implemento y no agrega dos puntos a ninguna de las listas
Hola, gracias por el curso esta muy interesante, tengo una duda
println y print son diferentes en kotlin?
Ambos pintan en pantalla, la diferencia es que println da un salto de linea antes de escribir.
consulta como puedo agrupar valores iguales en una lista dentro de una lista. que los diferencie dentro de una lista total.
ejemplo: en una lista tengo muchos colores y algunos repetidos. entonces lo que quiero saber la cantidad q tengo de cada color. osea separarlos en cada lista
Arist te sigo y veo tus videos. soy junior en Android y toda esta información me sirve de muchísimo. Saludos