If I want to collect my Kotlin collection into something that isn't built into the stdlib, how do I do it?
Event streams have become standard on Android. For years, RxJava has been the standard for reactive streams. Now, Kotlin provides its own reactive streams implementation, called Flow.
The most common way to create a collection is with the standard library functions listOf<T>() , setOf<T>() , mutableListOf<T>() , mutableSetOf<T>() . If you provide a comma-separated list of collection elements as arguments, the compiler detects the element type automatically.
Java Stream collect() is mostly used to collect the stream elements to a collection. It's a terminal operation. It takes care of synchronization when used with a parallel stream. The Collectors class provides a lot of Collector implementation to help us out.
However, Kotlin is eager by default, not lazy. This can cause additional work to be performed if we are not careful about the collection types that are being used.
For scenarios not covered by built in operations toList()
etc, you can use the fact that collect is just a fold. So given
val list: List<Pair<String, Int>> = listOf("Ann" to 19, "John" to 23)
you can collect to a collection of your choice with a fold
val map: Map<String, Int> = list.fold(HashMap(), { accumulator, item ->
accumulator.put(item.first, item.second); accumulator})
If you then define an extension function
fun <T, R> Iterable<T>.collectTo(accumulator: R, accumulation: (R, T) -> Unit) =
this.fold(accumulator, { accumulator, item -> accumulation(accumulator, item); accumulator } )
you can further simplify
val map2: Map<String, Int> = list.collectTo(HashMap(), { accumulator, item ->
accumulator.put(item.first, item.second) })
Although in this case of course you could just use the .toMap
extension function.
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