将Java的未来转换为Scala的未来

nimxete2  于 2022-11-09  发布在  Scala
关注(0)|答案(4)|浏览(159)

我有一个Java Future对象,我想将其转换为Scala Future
看看j.u.c.Future API,除了isDone方法之外,我没有什么可以使用的。这是isDone方法阻塞吗?
目前我的想法是这样的:

val p = Promise()
if (javaFuture.isDone())
  p.success(javaFuture.get)

有没有更好的方法来做这件事?

rt4zxlrg

rt4zxlrg1#

Scala 2.13开始,标准库包括scala.jdk.FutureConverters,它提供Java到Scala CompletableFuture/Future的隐式转换:

import scala.jdk.FutureConverters._

// val javaFuture = java.util.concurrent.CompletableFuture.completedFuture(12)
val scalaFuture = javaFuture.asScala
// scalaFuture: scala.concurrent.Future[Int] = Future(Success(12))
mm5n2pyu

mm5n2pyu2#

简单地 Package 它怎么样(我假设这里有一个隐式的ExecutionContext):

val scalaFuture = Future {
    javaFuture.get
}

编辑:
一个简单的轮询策略可能如下所示(java.util.Future=>F):

def pollForResult[T](f: F[T]): Future[T] = Future {
    Thread.sleep(500)
    f
  }.flatMap(f => if (f.isDone) Future { f.get } else pollForResult(f))

这将检查Java的未来是否每隔500ms完成一次。显然,总阻塞时间与上面相同(向上舍入到最接近的500ms),但这个解决方案将允许其他任务在ExecutionContext的同一线程中交错。

41zrol4v

41zrol4v3#

对于现在正在阅读此问题的读者,如果您使用的是Scala 2.13及更高版本,请使用:

import scala.jdk.FutureConverters._

并使用completableFuture.asScala进行转换
如果您使用的是Scala 2.12及更低版本,请使用

import scala.compat.java8.FutureConverters._

并使用:toScala(completableFuture)completableFuture.toScala进行转换
此外,在Scala 2.12中,请确保您使用的是正确的构件:

org.scala-lang.modules:scala-java8-compat_2.12:0.9.0

现在,如果出于某种原因,您拥有的实际上是Future而不是CompletableFuture,这在当今应该是罕见的情况,请遵循第一个答案:Transform Java Future into a CompletableFuture

cgyqldqp

cgyqldqp4#

使用FutureConvertors(Scala中内置的util)将Java Future转换为Scala Future。
考虑一个将Java Future[Int]转换为Scala Future[Int]的示例:

import java.util.concurrent.CompletableFuture
import scala.compat.java8.FutureConverters

val javaFuture: java.util.concurrent.Future[Int] = ??? 
// Some method call which returns Java's Future[Int]

val scalaFuture: Future[Int] = 
FutureConverters.toScala(CompletableFuture.supplyAsync(new Supplier[Int] {
      override def get(): Int = javaFuture.get 
    }))

类似于我们可以对任何自定义类型而不是Int执行的操作。

相关问题