Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Kotlin equivalent of Java Stream.collect?

If I want to collect my Kotlin collection into something that isn't built into the stdlib, how do I do it?

like image 531
Duncan McGregor Avatar asked Jan 06 '16 17:01

Duncan McGregor


People also ask

Do we have streams in Kotlin?

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.

How do you create a collection on Kotlin?

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.

What is Java Stream collect?

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.

Are Kotlin streams lazy?

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.


1 Answers

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.

like image 186
Duncan McGregor Avatar answered Oct 21 '22 18:10

Duncan McGregor