将 Java Future 转换为 Scala Future
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35033290/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert a Java Future to a Scala Future
提问by sparkr
I have a Java Futureobject which I would like to convert into a Scala Future.
我有一个Java Future对象,我想将其转换为Scala Future.
Looking at the j.u.c.FutureAPI, there is nothing much that I could use other than the isDonemethod. Is this isDonemethod blocking?
看看j.u.c.FutureAPI,除了方法之外,我没有什么可以使用的isDone。这个isDone方法会阻塞吗?
Currently this is what I have in my mind:
目前我的想法是这样的:
val p = Promise()
if (javaFuture.isDone())
p.success(javaFuture.get)
Is there a better way to do this?
有一个更好的方法吗?
回答by pablochan
How about just wrapping it (I'm assuming there's an implicit ExecutionContext here):
包装它怎么样(我假设这里有一个隐式的 ExecutionContext ):
val scalaFuture = Future {
javaFuture.get
}
EDIT:
编辑:
A simple polling strategy could look like this (java.util.Future => F):
一个简单的轮询策略可能如下所示(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))
This will check if the Java future is done every 500ms. Obviously the total blocking time is the same as above (rounded up to the nearest 500ms) but this solution will allow other tasks to be interleaved in the same thread of the ExecutionContext.
这将检查 Java 未来是否每 500 毫秒完成一次。显然,总阻塞时间与上面相同(四舍五入到最接近的 500 毫秒),但该解决方案将允许其他任务在ExecutionContext.
回答by Xavier Guihot
Starting Scala 2.13, the standard library includes scala.jdk.FutureConverterswhich provides Java to Scala CompletableFuture/Futureimplicit conversions:
开始Scala 2.13,标准库包括scala.jdk.FutureConverters提供 Java 到 ScalaCompletableFuture/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))
回答by Sanjyot Bandal
Use FutureConvertors (built-in util in Scala) for conversion of Java Future to Scala Future.
使用 FutureConvertors(Scala 中的内置工具)将 Java Future 转换为 Scala Future。
Consider an example for converting Java Future[Int] to Scala Future[Int] ::
考虑一个将 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
}))
Similar we can do for any custom type instead of Int.
类似的我们可以为任何自定义类型而不是 Int 做。
回答by Alexey Soshin
For those reading this question now, if you're using Scala 2.13 and above, use:
对于现在阅读此问题的人,如果您使用的是 Scala 2.13 及更高版本,请使用:
import scala.jdk.FutureConverters._
And convert using completableFuture.asScala
并转换使用 completableFuture.asScala
If you're using Scala 2.12 and below, use
如果您使用的是 Scala 2.12 及以下版本,请使用
import scala.compat.java8.FutureConverters._
And convert using: toScala(completableFuture)or completableFuture.toScala
并转换使用:toScala(completableFuture)或completableFuture.toScala
Also, in Scala 2.12 make sure you're using the correct artifact:
此外,在 Scala 2.12 中,请确保您使用的是正确的工件:
org.scala-lang.modules:scala-java8-compat_2.12:0.9.0
Now, if for some reason what you have is actually a Futureand not CompletableFuture, which should be a rare case nowadays, please follow first one of those answers: Transform Java Future into a CompletableFuture
现在,如果由于某种原因你所拥有的实际上是 aFuture和 not CompletableFuture,这在当今应该是一种罕见的情况,请遵循这些答案中的第一个:将 Java Future 转换为 CompletableFuture

