2015-09-11 72 views
3

scala Future類有幾種基於函數式編程的方法。從Java調用時,看起來像使用Java 8中的lambdas是非常合適的。使用scala.Future與Java 8 lambdas

但是,當我嘗試實際使用它時,遇到了幾個問題。以下代碼無法編譯

someScalaFuture.map(val -> Math.sqrt(val)). 
     map(val -> val + 3); 

因爲映射將ExecutionContext作爲隱式參數。在Scala中,您可以(通常)忽略它,但它需要在Java中明確傳入。

someScalaFuture.map(val -> Math.sqrt(val), 
        ec). 
     map(val -> val + 3, 
      ec); 

這種失敗,此錯誤:

error: method map in interface Future<T> cannot be applied to given types; 
[ERROR] val),ExecutionContextExecutor 
    reason: cannot infer type-variable(s) S 
    (argument mismatch; Function1 is not a functional interface 
     multiple non-overriding abstract methods found in interface Function1) 
    where S,T are type-variables: 
    S extends Object declared in method <S>map(Function1<T,S>,ExecutionContext) 
    T extends Object declared in interface Future 

如果我真正創建一個匿名類擴展功能1和實施apply這樣:

someScalaFuture.map(new Function1<Double, Double>() { 
      public double apply(double val) { return Math.sqrt(val); } 
     }, 
     ec). 
     map(val -> val + 3, 
      ec); 

我得到一個錯誤,

error: <anonymous com.example.MyTestClass$1> is not abstract and does not override abstract method apply$mcVJ$sp(long) in Function1 

我還沒有嘗試過實現該方法(並且我不確定是否可以在名稱中間實現一個帶有美元符號的方法),但是這看起來像我開始懷疑Scala實現的細節。

我會走下一條可行的道路嗎?以這種方式使用lambda是否有合理的方法?如果有一個庫使得這個工作,這是一個可以接受的解決方案。理想情況下,如

import static org.thirdparty.MakeLambdasWork.wrap; 
... 
    wrap(someScalaFuture).map(val -> Math.sqrt(val)). 
     map(val -> val + 3); 
+0

你想與做這個什麼版本的斯卡拉的? – childofsoong

+0

我正在使用Scala 2.11 –

回答

0

正如@Seth提到你可以使用scala-java8-compat

import scala.concurrent.Future; 
import static scala.compat.java8.FutureConverters.globalExecutionContext; 
import static scala.compat.java8.JFunction.func; 
... 

Future<Object> future = ...; 

future.onComplete(
    func(x -> ...), /// wraps Java lambda into a Scala Function 
    globalExecutionContext());// Gets the global execution context. 

Scala 2.12 introduced features to make it more compatible with Java,現在你可以使用lambda表達式直接

Future<Object> future = ...; 

future.onComplete(
    x -> ..., // Uses Java lambda directly 
    globalExecutionContext()); // Gets the global execution context. 

ExecutionContext.global基本上是管理有限數量由ForkJoinPool支持執行上下文線程。

如果您需要獲得更多的信息,我建議這兩個環節

Execution Context in Futures

When in doubt, stick with scala.concurrent.ExecutionContext.global