java.util.function.BiConsumer <r,r>)不适用(无法推断类型变量R)

时间:2015-11-03 20:36:13

标签: java concurrency java-stream reduce collect

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

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

我想在compare results对象

上收集n Result

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

我有这段代码

请求的类型为string

类型为report

的sumReport

类型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))

3 个答案:

答案 0 :(得分:1)

最好的猜测 - 您还没有提供太多详细信息 - 我希望您所需要的只是Report.add,或多或少地说:为累加器创建新的报告,调用Report要向Report.add添加元素,并调用Report(可能是不同的重载),将第二个Report合并到第一个links = {} for l in every_link: links[l] = {} for i in contractions_list: count = 0 ... #here is where you do your count, which you seem to know how to do ... #note that in your code, i think you meant if i in word/ if i == word for your final if statement if count: links[l][i] = count #only adds the value if count is not 0 中。

答案 1 :(得分:0)

有趣的是,如果你改为呼叫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);

答案 2 :(得分:0)

我认为这是由于JDK错误:在某些情况下JDK 1.8.0_25没有正确地重新协调lambda。

类似的帖子here得出了同样的结论。

我建议您将sdk版本( java -version )更新为至少1.8.0_45