java.util.function.BiConsumer<R,R>) 不适用(无法推断类型变量 R
java.util.function.BiConsumer<R,R>) is not applicable (cannot infer type-variable(s) R
我尝试编写一些流代码,将 report
个对象减少为一个 report
个对象。
我有这个 java 代码
获取字符串(请求)获取 http 响应 --> 将其传递给与保存在内存中的旧响应进行比较。
我想收集 n compare results
到 Result
个对象
最终我想将 m report
个对象聚合为一个对象。
我有这个代码
请求的类型为 string
report
类型的总报表
compare result
类型的比较 2
和:
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))
最好的猜测——你没有提供太多细节——我希望你需要的只是 collect(Report::new, Report::add, Report::add)
,这或多或少说:为累加器创建新的报告,调用 Report.add
将元素添加到 Report
,并调用 Report.add
(可能是不同的重载)将第二个 Report
组合到第一个 Report
).
有趣的是,如果您改为调用 reduce()
,它会编译。
通常,第一个参数可以为类型推断提供一些约束;不幸的是,您在这里使用 null
。仅通过查看方法调用,无法判断 R
可以是什么。幸运的是,方法调用是在赋值上下文中,因此 R
可以推断为 Report
.
唯一的问题是 lambda 体内的 value-return 语句,而函数类型应该是 void-return。由于 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);
我认为这是由于 JDK 错误造成的:在某些情况下,JDK 1.8.0_25 无法正确重新调整 lambda。
一个类似的线程得出相同的结论。
我建议您将您的 sdk 版本 (java -version) 至少更新到 1.8。0_45
我尝试编写一些流代码,将 report
个对象减少为一个 report
个对象。
我有这个 java 代码 获取字符串(请求)获取 http 响应 --> 将其传递给与保存在内存中的旧响应进行比较。
我想收集 n compare results
到 Result
个对象
最终我想将 m report
个对象聚合为一个对象。
我有这个代码
请求的类型为 string
report
compare result
和:
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))
最好的猜测——你没有提供太多细节——我希望你需要的只是 collect(Report::new, Report::add, Report::add)
,这或多或少说:为累加器创建新的报告,调用 Report.add
将元素添加到 Report
,并调用 Report.add
(可能是不同的重载)将第二个 Report
组合到第一个 Report
).
有趣的是,如果您改为调用 reduce()
,它会编译。
通常,第一个参数可以为类型推断提供一些约束;不幸的是,您在这里使用 null
。仅通过查看方法调用,无法判断 R
可以是什么。幸运的是,方法调用是在赋值上下文中,因此 R
可以推断为 Report
.
唯一的问题是 lambda 体内的 value-return 语句,而函数类型应该是 void-return。由于 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);
我认为这是由于 JDK 错误造成的:在某些情况下,JDK 1.8.0_25 无法正确重新调整 lambda。
一个类似的线程
我建议您将您的 sdk 版本 (java -version) 至少更新到 1.8。0_45