如何从 groovy 调用 Java 的 Stream.collect()?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33212660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 21:21:46  来源:igfitidea点击:

How to call Java's Stream.collect() from groovy?

javagroovyjava-stream

提问by Jerzyna

Having some background with FP from Scala I really don't like Groovy's names for collections methods. Given that and some architectural choices made above, I found using a Java 8 streams API (plus java.util.Optional) in Groovy code an appealing solution.

有一些 Scala 的 FP 背景,我真的不喜欢 Groovy 的集合方法名称。鉴于此以及上面做出的一些架构选择,我发现在 Groovy 代码中使用 Java 8 流 API(加上 java.util.Optional)是一个有吸引力的解决方案。

Until I hit this:

直到我击中这个:

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!

Note it works only in Groovy 2+ - treating closure as lambda. What bothers me is the last line of the example code. Groovy translates the call to the DefaultGroovyMethods.collect()instead of Stream.collect()that I originally wanted to use. Of course then the last line would be:

请注意,它仅适用于 Groovy 2+ -将闭包视为 lambda。困扰我的是示例代码的最后一行。Groovy 将调用转换为DefaultGroovyMethods.collect()而不是Stream.collect()我最初想要使用的。当然,最后一行将是:

        .collect(Collectors.toList()) //Should call Java collect, but it doesn't

It seems counter-intuitive to me, that some extension method is called instead of native, 'built-in' method of the class.

对我来说似乎违反直觉,调用一些扩展方法而不是类的本机“内置”方法。

How can I rewrite the example so the Stream.collect()method would be called?

如何重写示例以便Stream.collect()调用该方法?

UPDATE: After some more fiddling, I've found out what problem I had originally. I wrote .collect{Collectors.toList()}(note curly braces), which of course called Groovy method, not Java. Note to self: remember to quadruple-check before posting...

更新:经过更多的摆弄之后,我发现了我最初遇到的问题。我写的.collect{Collectors.toList()}(注意大括号),当然叫Groovy方法,而不是Java。自我注意:记得在发帖前四重检查......

采纳答案by jalopaba

Using Collectors.toList()you can get what you want to do:

使用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']

Anyway, with groovy 2.4.5 the above is working also with

无论如何,使用 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()

that uses groovy's collect:

使用groovy 的 collect

transforming each item into a new value using Closure.IDENTITY as a transformer, basically returning a list of items copied from the original object.

使用 Closure.IDENTITY 作为转换器将每个项目转换为新值,基本上返回从原始对象复制的项目列表。