我尝试编写一些流代码,将report
对象简化为一个report
对象。
我有这个java代码
接受字符串(请求)获取http响应->将其传递给与保存在内存中的旧响应进行某种比较。
我想将n个compare results
收集到Result
对象上
最终我想将m report
个对象聚合为一个对象。
我有这个代码
请求的类型为string
类型为report
的sumReportcompare 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);