Jer*_*yna 6 java groovy java-stream
有一些 Scala 的 FP 背景,我真的不喜欢 Groovy 的集合方法名称。鉴于此以及上面做出的一些架构选择,我发现在 Groovy 代码中使用 Java 8 流 API(加上 java.util.Optional)是一个有吸引力的解决方案。
直到我击中这个:
def finalCollection = [ 'some', 'items', 'really', 'not', 'important' ].stream()
.map { aMethodReturningOptional(it) } //map String to Optional<Item>
.flatMap { it.map(Stream.&of).orElseGet(Stream.&empty) } //convert to Stream<Item>
.collect() //Groovy's collect, not stream's!
Run Code Online (Sandbox Code Playgroud)
请注意,它仅适用于 Groovy 2+ -将闭包视为 lambda。困扰我的是示例代码的最后一行。Groovy 将调用转换为DefaultGroovyMethods.collect()而不是Stream.collect()我最初想要使用的。当然,最后一行将是:
.collect(Collectors.toList()) //Should call Java collect, but it doesn't
Run Code Online (Sandbox Code Playgroud)
对我来说似乎违反直觉,调用了一些扩展方法而不是类的本机“内置”方法。
如何重写示例以便Stream.collect()调用该方法?
更新:经过更多的摆弄之后,我发现了我最初遇到的问题。我写的.collect{Collectors.toList()}(注意大括号),当然叫Groovy方法,而不是Java。自我注意:记得在发帖前进行四重检查...
使用Collectors.toList()你可以得到你想做的事情:
import java.util.stream.*
class Item {
final String name
Item(name) {
this.name = name
}
@Override
String toString() {
name
}
}
def itemize(String name) {
Optional.of(new Item(name))
}
def finalCollection = [ 'some', 'items', 'really', 'not', 'important' ].stream()
.map { itemize(it) } //map String to Optional<Item>
.flatMap { it.map(Stream.&of).orElseGet(Stream.&empty) } //convert to Stream<Item>
.collect (Collectors.toList())
assert 'java.util.ArrayList' == finalCollection.class.name
assert finalCollection.collect { it.name } == ['some', 'items', 'really', 'not', 'important']
Run Code Online (Sandbox Code Playgroud)
不管怎样,在 groovy 2.4.5 中,上面的内容也适用于
def finalCollection = [ 'some', 'items', 'really', 'not', 'important' ].stream()
.map { itemize(it) } //map String to Optional<Item>
.flatMap { it.map(Stream.&of).orElseGet(Stream.&empty) } //convert to Stream<Item>
.collect()
Run Code Online (Sandbox Code Playgroud)
使用 Closure.IDENTITY 作为转换器将每个项目转换为新值,基本上返回从原始对象复制的项目列表。
| 归档时间: |
|
| 查看次数: |
20120 次 |
| 最近记录: |