Is there an equivalent Kotlin function for Java 8 Stream limit function

I am trying to find the first two elements in a list that matches a condition (filtering), for this purpose I implemented the following code in kotlin:

val arr = 0 until 20 val res = arr.filter { i -> println("Filter: $i") i % 2 == 0 }.take(2) 

Everything was fine until I realized that it filters the entire list, regardless of whether two items were found.

Using the Java 8 stream api stream, it works as expected.

 val res2 = arr.toList().stream() .filter { i -> println("Filter: $i") i % 2 == 0 }.limit(2) 

So, my questions, if they can be achieved using only the functions of Kotlin.

I know that I can use a simple loop, but I want to use aproach for functional programming.

+5
source share
2 answers

Kotlin, by default, performs these operations impatiently , while threads in Java are lazy . You can have the same behavior in Kotlin if you work with sequences that can be easily generated from Array or Iterable with asSequence() .

 arr.asSequence().filter { i -> println("Filter: $i") i % 2 == 0 }.take(2).toList() //Filter: 0 //Filter: 1 //Filter: 2 

Note that the sequence must be converted back to a list at the end.

You can read the details here.

+10
source

Using a sequence, you can get a lazy rating as a Java 8 stream. I rewrote your example with a lazy sequence and explicit types (I didn't change them, I just declared them for clarity):

 val arr: IntRange = 0 until 20 val res: List<Int> = arr .asSequence() .filter { i -> println("Filter: $i") i % 2 == 0 } .take(2) .toList() // Prints Filter: 0 Filter: 1 Filter: 2 And res == [0, 2] 

By arr into a sequence, doing your filter and take (like the Java limit ), and returning it to the list, it will execute lazily.

From the documentation for the sequence :

A sequence that returns values ​​through its iterator. Values ​​are evaluated lazily and the sequence is potentially endless.

+7
source

Source: https://habr.com/ru/post/1275004/


All Articles