Is there a reason why there are multiple ways to do the same thing in Kotlin
val viaSequence = items.asSequence()
.filter { it%2 == 0 }
.map { it*2 }
.toList()
println(viaSequence)
val viaIterable = items.asIterable()
.filter { it%2 == 0 }
.map { it*2 }
.toList()
println(viaIterable)
val viaStream = items.stream()
.filter { it%2 == 0 }
.map { it*2 }
.toList()
println(viaStream)
I know that the following code creates a list on every step, which adds load to the GC, and as such should be avoided:
items.filter { it%2 == 0 }.map { it*2 }
Streams come from Java, where there are no inline functions, so Streams are the only way to use these functional chains on a collection in Java. Kotlin can do them directly on Iterables, which is better for performance in many cases because intermediate Stream or Sequence objects don't need to be created.
Kotlin has Sequences as an alternative to Streams with these advantages:
Sequence.groupBy to Stream.collect).sequence builder lets you create a complicated lazy sequence of items with simple sequential syntax in a coroutine. Very powerful.The other answer mentions the advantages that Streams have.
In most cases it's best for performance and code clarity to directly use the Iterable inline operator functions rather than Sequences or Streams. Aside from when you're using the sequence builder for lazily generating items, I would default to picking Iterable operators, and only consider and experiment with Sequences if there is a performance bottleneck that needs to be optimized. More often than not, you'll probably find that you can't get the Sequence way of doing it to perform better than the Iterable operators anyway.
Nice article comparing them here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With