· 4 min read

Functional operations with collections in Kotlin (KAD 11)

I must admit that, for me, one of the most frustrating things when writing Java code is the list handling.

Java 8 has some improvements in this respect with Streams, but the syntax in Kotlin, thanks to what we saw earlier on how to compact the code when we have high order functions, greatly simplifies the process.

Functional operations over collections in Kotlin

Although I will not show you all the operations that exist (there are a lot), I want to show you some interesting things you can do with them.

If you want a more complete list, you can have a look at this article I wrote some time ago.

If you want to start today, I recommend you take a look at my free training, where you will have an hour and a half of content to know what are your next steps to become an expert in Kotlin.

Here are some of the most interesting:

forEach

With it, you can iterate over each element of the collection without further complications:

viewGroup.children.forEach { v -> v.visibility = VISIBLE }

Remember that, with the use of it, this can be converted into:

viewGroup.children.forEach { it.visibility = VISIBLE }

viewGroup.children does not exist as such on Android, but we saw in an earlier article how to get this with an extension property.

map

It is an operation that maps each of the objects in a list to a new list, after doing some kind of transformation. Returning to the previous ViewGroup example:

val childViews = (0..viewGroup.childCount - 1).map { viewGroup.getChildAt(it) }

The map operation in this case maps a range of integers (we’ve already talked about ranges previously), which is a collection, to a new collection of views corresponding to the children of the ViewGroup.

In a later article we’ll see how we can avoid the redundancy of referring to the ViewGroup several times in the same block of code.

filter

As its own name suggests, filter allows us to filter the elements of a collection that meet a specific condition.

For example, if we wanted to filter the child views of a ViewGroup which in turn are a ViewGroup:

val childViews = viewGroup.children.filter { it is ViewGroup }

For this particular case, we actually have a filterIsInstance that you could use:

val childViews = viewGroup.children.filterIsInstance<ViewGroup>()

There are several more filtering types, such as filterNotNull, that will discard null items, or filterNot, which keeps those that do not meet the condition.

first / last

Related to the previous one, they return the first or last element of the list that fulfills certain condition:

val firstTextView = viewGroup.children.first { it is TextView }
val lastTextView = viewGroup.children.last { it is TextView }

These functions would throw an exception if they don’t find any element that satisfies the condition. An alternative is to use firstOrNull, which will return null in that case.

sort

Sorting elements in Java always becomes a small headache, and the resulting code is not very readable.

However, with Kotlin we can make it much easier, since we can sort by any condition.

Although it may not make much sense, here I will order the view children of a ViewGroup by their visibility. This field is an integer in the View class, so it is very clear which view is larger or smaller than another:

val firstTextView = viewGroup.children.sortedBy { it.visibility }

Combination of operations

Of course, all these operations can be combined as we want, in such a way that in very little space we can do quite complex operations:

(0..viewGroup.childCount - 1)
    .map { viewGroup.getChildAt(it) }
    .filterIsInstance<ViewGroup>()
    .sortedBy { it.visibility }
    .takeWhile { it.visibility < View.GONE }

Here, for example, all views in a ViewGroup that also are ViewGroup are recovered, sorted by visibility, and those that have visibility lower than GONE (ie VISIBLE and INVISIBLE) are taken.

And not only is it very powerful, but it’s a lot easier to read than if you did the same thing with Java 6.

Conclusion

The operations over collections in Kotlin allow us to save many lines of code gaining in expressivity and readability.

This also helps make it much harder to add errors to the code. All pros!

If all this passionate you as to me, I encourage you to sign up for my free training where I will tell you everything you need to learn about how to create your own Android Apps in Kotlin from scratch.

    Share:
    Back to Blog