我理解
e.g。
map.getOrElse("key1","default")
与此同时,我正在与Java库进行交互,其中某些值为null。
e.g。 地图( “KEY1” - >空)
在这种情况下, getOrElse
将抛出空指针。
我想要处理这两种情况并导致写出类似这样的内容
def getOrElseNoNull[A,B](map:Map[A,B],key:A,default:B) = {
map.get(key) match{
case Some(x) if x != null => x
case _ => default
}
}
非常难看。 (它是Map [Any],我需要一个来自该键的字符串)
getOrElseNoNull(map,"key1","").asInstanceOf[String])
是否可以使用隐式扩展地图或任何其他优雅方式?
答案 0 :(得分:7)
如果你正在处理一个不可变的Map,最安全的做法是预先过滤掉所有的null值(这会导致另一个Map实例的创建,但除非你有特别的理由要关心这里的表现应该不是问题。)
strlen
任何持有null的键都消失了,因此此键上的val withoutNulls = map.filter{case (k,v)=> v != null}
将返回getOrElse
。
琐碎,并为所有人做了一次工作。
答案 1 :(得分:4)
implicit class NullOccludingMap[K, V](private val underlying: Map[K, V]) extends AnyVal {
def getNonNullOrElse(key: K, default: V): V = {
underlying.get(key) match {
case Some(value) if value != null => value
case _ => default
}
}
}
然后你可以在范围内的任何地方使用它:
val test = Map("x" -> "Hi", "y" -> null)
test.getNonNullOrElse("z", "") // ""
test.getNonNullOrElse("y", "") // ""
答案 2 :(得分:1)
一种可能性是将值映射到Option()
:
val withoutNulls: Map[Int, Option[String]] = withNulls.mapValues(Option.apply)
这使您可以以相同的方式处理缺失值和null:
val nullsEqualMissing: Map[Int, Option[String]] = withoutNulls.withDefaultValue(None)
nullsEqualMissing(1).fold{ "nullOrMissing" }{ identity }
或单独处理缺失值:
withoutNulls.get(1).fold{ "missing" }{ _.fold{ "null" }{ identity }}
答案 3 :(得分:0)
没有必要创建新的东西,scala支持几种使用默认值实现此目的的方法:
// define a function to handle special values
Map("1" -> "2").withDefault( _ => "3").apply("4")
// default values for all unknown values
Map("1" -> "2").withDefaultValue("3").apply("4")
// handle a specific case
Map("1" -> "2").getOrElse("unknown", "3")
另一种选择是使用Option以较不丑的方式获取null值:
None.orNull
这将获得Option值,如果为None,则返回null。
答案 4 :(得分:0)
另一个简单的解决方案是使用Scala Option包装map.get结果。
val value = Option(map.get(key))