处理Scala映射中缺少键和空值的优雅方式
我明白处理Scala映射中缺少键和空值的优雅方式,scala,Scala,我明白 在Scala中,应避免使用null 和Map.get将返回一个选项[B],我可以使用.getOrElse获取该值并返回默认值 e、 g 同时,我正在与一个Java库交互,其中一些值为空 e、 g。 映射(“键1”->null) 在这种情况下,getOrElse将抛出空指针 我想处理这两种情况,并得出这样的结论 def getOrElseNoNull[A,B](map:Map[A,B],key:A,default:B) = { map.get(key) match{
- 在Scala中,应避免使用null
- 和Map.get将返回一个选项[B],我可以使用.getOrElse获取该值并返回默认值
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],我需要该键的字符串)
是否可以使用implicit来扩展地图,或使用任何其他优雅的方式?来拯救:
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", "") // ""
实际上不需要创建新的内容,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")
另一个选项是使用该选项以不太难看的方式获取空值:
None.orNull
这将获得选项值,如果没有,则返回null。一种可能性是将值映射到
选项()
:
这使您能够以相同的方式处理缺少的值和空值:
val nullsEqualMissing: Map[Int, Option[String]] = withoutNulls.withDefaultValue(None)
nullsEqualMissing(1).fold{ "nullOrMissing" }{ identity }
或单独处理缺少的值:
withoutNulls.get(1).fold{ "missing" }{ _.fold{ "null" }{ identity }}
如果您处理的是一个不可变映射,最安全的做法是预先过滤掉所有空值(这会导致创建另一个映射实例,但除非您有特定的原因关心这里的性能,否则这不应该是一个问题) 任何保留null的键都将消失,因此此键上的
getOrElse
将返回None
。
另一个简单的解决方案是使用Scala选项包装map.get结果
val value = Option(map.get(key))
val nullsEqualMissing: Map[Int, Option[String]] = withoutNulls.withDefaultValue(None)
nullsEqualMissing(1).fold{ "nullOrMissing" }{ identity }
withoutNulls.get(1).fold{ "missing" }{ _.fold{ "null" }{ identity }}
val withoutNulls = map.filter{case (k,v)=> v != null}
val value = Option(map.get(key))