是否有任何相当于Java 8 Stream限制function的Kotlin函数?
我试图find符合条件(过滤)的列表中的前两个元素,为此,我已经在kotlin中实现了以下代码片段:
val arr = 0 until 20 val res = arr.filter { i -> println("Filter: $i") i % 2 == 0 }.take(2)
一切都很好,直到我意识到它通过整个清单过滤,无论是否find了这两个元素。
利用Java 8流API,它按预期工作。
val res2 = arr.toList().stream() .filter { i -> println("Filter: $i") i % 2 == 0 }.limit(2)
所以我的问题是,如果只能使用Kotlin函数来实现。
我知道我可以使用一个简单的循环,但我想使用一个函数式编程aproach。
Kotlin在默认情况下会热切地执行这些操作,而Java中的Streams是懒惰的 。 如果您使用序列 (可以很容易地从Array
s生成)或者使用asSequence()
Iterable
s生成序列 ,那么您可以在Kotlin中拥有相同的结果。
arr.asSequence().filter { i -> println("Filter: $i") i % 2 == 0 }.take(2).toList() //Filter: 0 //Filter: 1 //Filter: 2
请注意,序列最后必须转换为列表。
你可以在这里阅读有关细节。
通过使用一个序列,你可以得到像Java 8流一样的惰性评估。 我用懒惰的顺序和显式types重写了你的例子(我没有改变它们,为了清楚起见,我只是宣布它们):
val arr: IntRange = 0 until 20 val res: List = arr .asSequence() .filter { i -> println("Filter: $i") i % 2 == 0 } .take(2) .toList() // Prints Filter: 0 Filter: 1 Filter: 2 And res == [0, 2]
通过将arr
转换成一个序列,执行你的filter
并take
(这就像Java的limit
),然后把它变成一个List,它将会懒惰地执行。
从序列的文档 :
通过其迭代器返回值的序列。 这些值是懒惰地评估的,序列可能是无限的。