我对Scala的FP有一定的了解,我真的不喜欢Groovy对集合方法的命名。考虑到这一点,以及上面所做的一些架构选择,我发现在Groovy代码中使用Java 8 streams 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!
注意,它只在Groovy 2+ -treating closure as lambda中有效。让我感到困扰的是示例代码的最后一行。Groovy将调用转换为DefaultGroovyMethods.collect()
,而不是我最初想要使用的Stream.collect()
。当然,最后一行应该是:
.collect(Collectors.toList()) //Should call Java collect, but it doesn't
在我看来,调用某个扩展方法而不是类的本机“内置”方法是违反直觉的。
如何重写示例,以便调用Stream.collect()
方法?
UPDATE:经过一番折腾,我发现了最初的问题。我编写了.collect{Collectors.toList()}
(注意大括号),它当然调用了Groovy方法,而不是Java。注意:请记住在发布前进行四次检查...
2条答案
按热度按时间bogh5gae1#
使用
Collectors.toList()
,您可以得到您想要的结果:无论如何,在groovy 2.4.5中,上面的代码也适用于
使用groovy的collect的代码:
使用Close.IDENTITY作为转换器将每个项转换为新值,基本上返回从原始对象复制的项的列表。
5w9g7ksd2#
Groovy 2.5.0和更高版本将
toList
和toSet
方法添加为enhancements to Stream。不再需要使用Collectors.toList()
。