/ KOTLIN, COLLECTION, SEQUENCE, STREAM, LAZY EVALUATION

Kotlin, collections and sequences

When streams were added to Java 8, I wanted to jump on the bandwagon. I read blog posts, watched videos, attended workshops to understand what this was all about. After a while, I became comfortable enough…​ but I was unhappy with the implementation: while streams offer methods with a functional approach, legacy collections do not.

When one wants to use Java capabilities on an existing collection, the later needs to be transformed to a stream, and then back again. For example, the following code filters out some elements from a collection, through a streaming step:

List<String> names = Arrays.asList("Joe", "Jack", "William", "Averell");
List<String> jNames = names.stream()
                           .filter(name -> name.startsWith("J"))
                           .collect(Collectors.toList());

On the other hand, Kotlin collections natively offer functional capabilities:

val names = listOf("Joe", "Jack", "William", "Averell")
val jNames = names.filter { it.startsWith("J") }

That’s the reason I thought it was a better approach (notice the past tense here). There’s a big catch, though: Kotlin functional functions are not lazily-evaluated, while Java stream’s functions are! This is perfectly fine if the collection contains only a few elements, but it can be a huge issue if there are many elements - or many steps in the processing pipeline.

Yet, Kotlin also provide a lazily-evaluated object: the Stream counterpart is Sequence:

class diagram
Common functions between collections and sequences

Though they share common functions, there’s no shared interface between Kotlin collections and Sequence. Their functions are generated through a macro-like script (see GenerateStandardLib for more details). For example, Sequence functions are defined as extensions in the generated kotlin.sequences._Sequences.kt file.

Conclusion

If a collection contains more than a few elements, or is bound to, then sequences should be preferred over collections. Otherwise, it’s perfectly fine to use standard collections, as they offer the same capabilities.

Nicolas Fränkel

Nicolas Fränkel

Nicolas Fränkel is a Developer Advocate with 15+ years experience consulting for many different customers, in a wide range of contexts (such as telecoms, banking, insurances, large retail and public sector). Usually working on Java/Java EE and Spring technologies, but with narrower interests like Software Quality, Build Processes and Rich Internet Applications. Currently working for Exoscale. Also double as a teacher in universities and higher education schools, a trainer and triples as a book author.

Read More