2015-11-03 44 views
0

我嘗試寫降低report對象到一個report對象一些流的代碼。java.util.function.BiConsumer <R,R>)是不適用(不能推斷類型變量(S)R

我有這樣的Java代碼這 取字符串(請求)GET HTTP響應 - >其傳遞到與保存在內存中舊有的反應比較

我想收集ňcompare results插入Result對象

,最終我想骨料。將對象合併到一個對象中。

我有此代碼

請求的類型爲string

類型的sumReport report

類型的比較2 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; 
         }); 

爲什麼d o我有這個錯誤?

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)) 
+1

*如何進行機制工作*:這是由javadoc的描述,在連篇累牘。你讀過了嗎?你認爲null是否是第一個參數的有效值? http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.function.Supplier-java.util.function.BiConsumer-java.util。 function.BiConsumer-。另外兩個參數是BiConsumers。一個BiConsumer(s accept方法返回什麼東西? –

+1

'collect'是一個* mutable * reduction。你不應該在累加器或組合器中返回任何東西。 –

+0

@PaulBoddington謝謝。我很困惑。重新編寫代碼,如果我不想要一個'report'列表,但最終會有一個彙總報告? –

回答

0

有趣的是,如果你調用reduce(),它會編譯。

通常,第一個參數可以爲類型推斷提供一些約束;不幸的是,您在這裏使用null。通過單獨查看方法調用,不可能告訴什麼是R。幸運的是,方法調用位於分配上下文中,因此R可以被推斷爲Report

唯一的問題是lambda體內的值返回語句,而功能類型應該是void-return。由於返回類型不同,它與reduce()一起使用。

編譯器使用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); 
1

在一個最好的猜測 - 您沒有提供太多細節 - 我期望你所需要的僅僅是collect(Report::new, Report::add, Report::add),它說或多或少:創建新的蓄電池的報告,呼籲Report.add添加一個元素設置爲Report,並且還調用Report.add(也許是不同的過載),以將第二個Report組合成第一個Report)。

+0

我會添加類型。對不起。你能修改你的答案嗎? –

+0

do調用相同的方法兩次有意義嗎?Report :: add,Report :: add' –

+0

它看起來像是不同的重載,但是,它是有道理的,它不是我需要的類型,確切地說,它幾乎是API de在你正在使用的所有課程中使用尾巴。 –

0

我認爲這是由於JDK錯誤:在某些情況下, JDK 1.8.0_25沒有正確重構lambda。

類似的線程here得出相同的結論。

我建議您更新SDK版本(Java的版本)至少1.8.0_45