将 Scala 选项转换为 Java 可选

Convert Scala Option to Java Optional

我需要将 Scala Option 转换为 Java Optional。我设法写了这个:

public <T> Optional<T> convertOption2Optional(Option<T> option) {
    return option.isDefined() ? Optional.of(option.get()) : Optional.empty();
}

但是我不喜欢。

有没有简单的方法或者内置的 Scala 转换器? 我正在寻找类似的东西:

Options.asJava(option);

我在Java中能想到的最短路线是:

Optional.ofNullable(option.getOrElse(null))

@RégisJean-Gilles 实际上建议如果您在 Scala 中编写转换则更短:

Optional.ofNullable(option.orNull)

顺便说一下,您必须知道 Scala 不支持 Java8 直到 Scala 2.12 尚未正式发布。查看 docs(在发布之前可能会更改)JavaConversions 中没有这样的转换。

您还可以在 github 上使用一些丰富的实用程序,例如:

https://gist.github.com/julienroubieu/fbb7e1467ab44203a09f

https://github.com/scala/scala-java8-compat

我正在这样做:

import java.util.{Optional => JOption}

package object myscala {

    implicit final class RichJOption[T](val optional: JOption[T]) {

        def asScala: Option[T] = optional match {
            case null => null
            case _ => if (optional.isPresent) Option(optional.get()) else None
        }

    }

    implicit final class RichOption[T](val option: Option[T]) {

        def asJava: JOption[T] = option match {
            case null => null
            case _ => if (option.isDefined) JOption.of(option.get) else JOption.empty()
        }

    }
}

所以,你可以这样使用它,:)

import myscala._

object Main extends App {

    val scalaOption = java.util.Optional.ofNullable("test").asScala
    println(scalaOption)

    val javaOption = Option("test").asJava
    println(javaOption)

}

另一个不错的库:

https://github.com/AVSystem/scala-commons

import com.avsystem.commons.jiop.JavaInterop._
Optional.of("anything").asScala

对于某些 class 的给定输入参数 opt: Option[T], 您可以在 class 中定义一个方法,如下所示:

def toOptional(implicit ev: Null <:< T): Optional[T] =
  Optional.ofNullable(opt.orNull)

Scala 2.13 开始,有一个从 scala 的 Option 到 java 的 Optional 的专用转换器。

From Java显式方式):

import scala.jdk.javaapi.OptionConverters;

// val option: Option[Int] = Some(42)
OptionConverters.toJava(option);
// java.util.Optional[Int] = Optional[42]

From Scala隐式方式):

import scala.jdk.OptionConverters._

// val option: Option[Int] = Some(42)
option.toJava
// java.util.Optional[Int] = Optional[42]

有一个 asJava2.10 开始:

import scala.compat.java8.OptionConverters._

val o = Option(2.7)
val oj = o.asJava        // Optional[Double]
val ojd = o.asPrimitive  // OptionalDouble
val ojds = ojd.asScala   // Option(2.7) again

更多详情here

例如,Scala 2.13 在 scala.jdk.OptionConverters.{RichOption, FutureConverters} 中有一些有用的转换器。

RichOption 添加了在 scala 和 java 选项之间转换的隐式方法,因此您可以这样做...

    import scala.jdk.OptionConverters.RichOption
    
    val scalaOpt = Some("hello")
    val javaOpt = scalaOpt.toJava

在幕后,这只是 scala 选项的匹配语句...

    def toJava: Optional[A] = o match { case Some(a) => Optional.ofNullable(a); case _ => Optional.empty[A] }