Reputation: 1357
What is the best alternative in Kotlin to java.util.stream.Stream<>.peek(...)?
Seems there are no alternative intermediate operations:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.streams/index.html
I found only terminating forEach(...)
Upvotes: 29
Views: 14690
Reputation: 446
You can use your own custom extension function, I use this for live data
inline fun <T> LiveData<T>.peek(crossinline block: (T) -> Unit): LiveData<T> {
return map {
block(it)
it
}
}
You could modify to get something like this.
inline fun <T> Stream<T>.peek(crossinline block: (T) -> Unit): Stream<T> {
return map {
block(it)
it
}
}
Similarly
inline fun <T> Sequence<T>.peek(crossinline action: (T) -> Unit): Sequence<T> {
return map {
action(it)
it
}
}
Then in your code
listOf(1, 2, 3, 4, 5)
.asSequence()
.filter { it < 4 }
.peek { println("peek $it") }
.map { it * 10 }
.peek { println("final: $it") }
Upvotes: 0
Reputation: 4524
Firstly, unlike Java in Kotlin, you can perform stream processing (map/reduce operations) on any type of collection for example:
val list = ArrayList<Int>()
list.forEach { }
list.onEach { }
However the operations defined in this way are not lazily evaluated and if we need lazy evaluation by applying the method .asSequence()
and generate a stream from collection.
Finally to answer your question onEach()
is the equivalent of peek()
Upvotes: 4
Reputation: 81879
The Stream alternative in Kotlin is Sequences.
listOf(1, 2, 3, 4, 5)
.asSequence()
.filter { it < 3 }
.onEach { println("filtered $it") }
.map { it * 10 }
.forEach { println("final: $it") }
There's onEach
to do what peek
does.
Fun fact: Kotlin also wanted to call their sequences "Streams" before it was clear that Java would do the same, so they renamed it to "Sequences".
Upvotes: 56