如何处理Scala中的Hashtable空值?

del*_*ber 4 scala scala-java-interop

我正在移植一些Java代码并具有以下内容

val overnightChanges: java.util.Hashtable[String, Double] = ...
Run Code Online (Sandbox Code Playgroud)

当我尝试

if (null != overnightChanges.get(...))
Run Code Online (Sandbox Code Playgroud)

我收到以下警告

警告:使用`!='比较Null和Double类型的值将始终为true

Did*_*ont 14

scala中的原始类型和引用类型与java中的不同,因此惯例是名称以所有类型的大写开头.Doublescala.Double原始java double,而不是引用java.lang.Double.

当您在scala中需要"双倍或无值"时,您将在Option[Double]大多数时间使用.Option具有强大的库支持,类型系统不会让您忽略可能没有值.但是,当你需要与java密切交互时,就像在你的例子中一样,你的表确实包含java.lang.Double,你应该这样说.

val a = new java.util.HashMap[String, java.lang.Double]
Run Code Online (Sandbox Code Playgroud)

如果java.lang.Double代码中的任何地方都出现了,则可以通过导入为别名添加别名

import java.lang.{Double => JDouble}
Run Code Online (Sandbox Code Playgroud)

或者通过定义

type JDouble = java.lang.Double 
Run Code Online (Sandbox Code Playgroud)

scala.Double和之间存在隐式转换java.lang.Double,因此交互应该相当平滑.但是,java.lang.Double应该可能仅限于scala/java交互层,让它深入到scala代码中会让人感到困惑.

  • 值得指出的是`Option(javaHashtable.get(...))`会将"java.lang.Double或null"转换为`Option [java.lang.Double]`.通常,使用`Option`包装可空的Java方法以防止`null`泄漏到Scala代码中是一种很好的做法. (2认同)

par*_*tic 5

在Scala中,Double是原语,因此不能为null.当直接使用java地图时这很烦人,因为当没有定义一个键时,你会得到默认的原始值,(这里是0.0):

scala>  val a = new java.util.Hashtable[String,Double]()
a: java.util.Hashtable[String,Double] = {}

scala> a.get("Foo")
res9: Double = 0.0
Run Code Online (Sandbox Code Playgroud)

如果值是String或List之类的对象,则代码应按预期工作.

因此,要解决问题,您可以:

  1. 使用contains中,如果条件外.
  2. 使用其中一个Scala映射(定义了许多转换scala.collection.JavaConversions)