【问题标题】:Convert Scala Option to Java Optional将 Scala 选项转换为 Java 选项
【发布时间】:2016-11-14 12:07:33
【问题描述】:

我需要将 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);

【问题讨论】:

  • 为什么不在自定义的Options 类中创建一个静态方法asJava(Option&lt;T&gt; opt)
  • 可以,但这是要维护的另一段代码,我想使用“标准方式”

标签: java scala scala-java-interop


【解决方案1】:

我能想到的Java中最短的方法是:

Optional.ofNullable(option.getOrElse(null))

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

Optional.ofNullable(option.orNull)

顺便说一句,你必须知道 Scala 直到 Scala 2.12 才支持 Java 8,它还没有正式发布。查看docs(可能会在发布之前更改)JavaConversions 中没有这样的转换。

【讨论】:

  • option.getOrElse(null) 可以缩短为option.orNull
  • 我在想一个 expr 中意外的多次转换,但谷歌搜索 scala javaconversions evil 会产生gist.github.com/xuwei-k/8870ea35c4bb6a4de05c,这非常好。我应该补充一点,我对此并没有强烈的感觉,Jason Zaugg 认为它对简洁很有用。弃用主要是为了帮助新手避免陷阱 (IMO)。
  • 第一个在 Java 中不起作用。 None.getOrElse(null) 抛出一个 NPE,因为 getOrElse 接受一个按名称参数,该参数转换为 scala.Function0
  • @Dici:我说的是用Java。您在 Scala 解释器中运行它。
【解决方案2】:

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]

【讨论】:

    【解决方案3】:

    现在有一个asJava 解决方案!可从2.10 获得。

    例子:

    import scala.compat.java8.OptionConverters._
    
    class Test {
      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.

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • java8 compat 曝光不足。
      【解决方案5】:

      我正在这样做:

      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)
      
      }
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

          另一个不错的库:

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

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

          【讨论】:

            【解决方案8】:

            例如,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] }
            

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-03-26
            • 1970-01-01
            • 2012-01-09
            • 2019-08-15
            相关资源
            最近更新 更多