Debo reconocer que, para mí, una de las cosas más frustrantes de programar en Java es el tratamiento de listas.
Java 8 tiene algunas mejoras a este respecto con los Streams, pero la sintaxis en Kotlin, gracias a lo que vimos anteriormente sobre la forma de compactar el código cuando tenemos funciones de alto orden, simplifica mucho el proceso.
Si quieres aprender cuál es la situación de Kotlin en el mercado, por qué debes aprenderlo y los primeros pasos para que veas lo fácil que es, he preparado un training gratuito de hora y media al que puedes unirte haciendo click aquí
Operaciones funcionales sobre colecciones en Kotlin
Aunque no te voy a mostrar todas las operaciones que existen, pues son mucha, sí que quiero enseñarte algunas cosas interesantes que puedes hacer con ellas.
Si quieres un listado completo, puedes echar un vistazo a este artículo en inglés que escribí hace tiempo.
Estas son algunas de las más interesantes:
forEach
Con ella puedes iterar sobre cada elemento de la colección sin más complicaciones:
viewGroup.children.forEach { v -> v.visibility = VISIBLE }
Recuerda que, con el uso it
, esto se puede convertir en:
viewGroup.children.forEach { it.visibility = VISIBLE }
viewGroup.children
no existe como tal en Android, pero vimos en un artículo anterior cómo conseguir esto con una propiedad de extensión.
map
Es una operación que mapea cada uno de los objetos de una lista en una nueva lista. Volviendo al ejemplo anterior del ViewGroup
:
val childViews = (0..viewGroup.childCount - 1).map { viewGroup.getChildAt(it)
La operación map
en este caso mapea un rango de enteros (ya vimos los rangos anteriormente), que es una colección, en una nueva colección de vistas correspondiente a las hijas del ViewGroup
.
En algún artículo posterior veremos cómo podemos evitar la redundancia de referirnos al ViewGroup
varias veces en un mismo bloque de código.
filter
Como su propia palabra indica, filter
nos permite filtrar los elementos de una colección que cumplan cierta condición que le indiquemos.
Por ejemplo, si quisiéramos filtrar las vistas hijas de un ViewGroup
que a su vez son ViewGroup
:
val childViews = viewGroup.children.filter { it is ViewGroup }
Para este caso en particular, en realidad tenemos un filterIsinstance
que se podría usar:
val childViews = viewGroup.children.filterIsInstance()
Hay varios tipos de filtrado más, como filterNotNull
, que se queda con los no nulos, o filterNot
, que se queda con los que no cumplan la condición.
first / last
Relacionado con el anterior, devuelven el primer o último elemento de la lista que cumplan cierta condición:
val firstTextView = viewGroup.children.first { it is TextView } val lastTextView = viewGroup.children.last { it is TextView }
Estas funciones lanzarían una excepción si no encuentran ningún elemento que cumpla la condición. Una alternativa es usar firstOrNull
, que devolverá null
en ese caso.
Si podemos, es mejor evitar trabajar con null
.
sort
Ordenar elementos en Java siempre se convierte en un pequeño dolor de cabeza, y el código resultante no es nada visual.
Sin embargo, con Kotlin podemos hacerlo mucho más sencillo, ya que podemos ordenar mediante cualquier condición.
Aunque pueda no tener mucho sentido, aquí voy a ordenar la vistas hijas de un ViewGroup
por su visibility
. Este campo es un entero en la clase View
, así que queda muy claro qué vista es mayor o menor que otra:
val firstTextView = viewGroup.children.sortedBy { it.visibility }
Combinación de operaciones
Por supuesto, todas estas operaciones se pueden combinar como queramos, de tal forma que en muy poco espacio podemos hacer operaciones bastante complejas:
(0..viewGroup.childCount - 1) .map { viewGroup.getChildAt(it) } .filterIsInstance() .sortedBy { it.visibility } .takeWhile { it.visibility < View.GONE }
Aquí, por ejemplo, se están recuperando todas las vistas de un ViewGroup
que a su vez son ViewGroup
, ordenadas por visibilidad, y se toman las que tengan visibilidad inferior a GONE
(es decir, VISIBLE
e INVISIBLE
).
Y no es sólo que sea muy potente, sino que es muchísimo más fácil de leer que si hicieras lo mismo con Java 6.
Conclusión
Las operaciones sobre colecciones en Kotlin nos permiten ahorrar muchísimas líneas de código ganando en expresividad y legibilidad.
Esto ayuda, además, a que sea mucho más difícil añadir errores en el código. ¡Todo ventajas!
Y si quieres aprender a utilizar Kotlin para desarrollar tus propias Apps Android, te recomiendo que le eches un vistazo al mi training gratuito. ¡Reserva tu plaza !
Qué entretenido leer todas las mañanas un post nuevo de Kotlin 😀
El tratamiento de colecciones es lo que más me hizo cambiar el chip a programación funcional pues te hace olvidar usar un bucle for para todo y andar con variables temporales.
Este verano estuve portando alguno de mis juegos Andriod (con Java) a Swift, que se parece bastante a Kotlin (quien se apunte a tu curso tiene medio camino hecho en Swift ya ;)) y al principio era un port casi literal. Luego lo volví a escribir “funcionalmente”, cambiar seis o siete o muchas más líneas de código por una perfectamente legible es una bendición.
P.D: El link al artículo en inglés lleva a esta misma página
Sí, son muy parecidos, yo le tengo ganas a Swift. Lo próximo debería ser Swift para desarrolladores Kotlin jajaja