我尝试编写一些流代码,将report对象简化为一个report对象。

我有这个java代码
接受字符串(请求)获取http响应->将其传递给与保存在内存中的旧响应进行某种比较。

我想将n个compare results收集到Result对象上

最终我想将m report个对象聚合为一个对象。

我有这个代码

请求的类型为string

类型为report的sumReport

compare result类型的compare2

和:

        Report report = requestsList
                .parallelStream()
                .map(request ->
                                getResponse(request, e2EResultLongBL, e2EResultLongFresh)
                )
                .map(response -> compareToBl(response, e2EResultLongBL))
                .collect(null,
                        (sumReport, compare2) ->
                        {
                            if (sumReport == null)
                            {
                                sumReport = new Report();
                            }
                            sumReport.add(compare2);
                            return  sumReport;
                        },
                        (report1, report2) ->
                        {
                            Report report3 = new Report();
                            report3.add(report2);
                            return report3;
                        });


为什么会出现此错误?

Error:(174, 21) java: no suitable method found for collect(<nulltype>,(sumReport[...]rt; },(report1,r[...]t3; })
    method java.util.stream.Stream.<R>collect(java.util.function.Supplier<R>,java.util.function.BiConsumer<R,? super com.waze.routing.automation.dataModel.ComparisonResult>,java.util.function.BiConsumer<R,R>) is not applicable
      (cannot infer type-variable(s) R
        (argument mismatch; unexpected return value))
    method java.util.stream.Stream.<R,A>collect(java.util.stream.Collector<? super com.waze.routing.automation.dataModel.ComparisonResult,A,R>) is not applicable
      (cannot infer type-variable(s) R,A
        (actual and formal argument lists differ in length))

最佳答案

有趣的是,如果您改为调用reduce(),它将进行编译。

通常,第一个参数可以为类型推断提供一些约束。不幸的是,您在这里使用null。仅查看方法调用,就无法说出R是什么。幸运的是,方法调用是在分配上下文中进行的,因此可以将R推断为Report

唯一的问题是lambda主体中的value-return语句,而功能类型应该是void-return。由于不同的返回类型,它可与reduce()一起使用。

编译器在lambda主体中使用return语句来约束lambda的类型,这在例如重载解析中非常有用

    ExecutorService es= ...;
    es.submit( ()->{ return new Object(); } );      // submit(Callable)
    es.submit( ()->{        new Object(); } );      // submit(Runnable)


处理void是一件棘手的事情,例如该代码无法编译,这是合理的

    Executor ex = null;
    ex.execute( ()->{ return new Object(); } ); // error, ()->void is expected


但是,这两种形式都可以编译,这也是合理且有用的

    ex.execute(()->new Object());
    ex.execute(Object::new);

09-04 06:32
查看更多