优雅的方式处理Scala Map中缺少的键和空值

时间:2015-07-02 03:49:43

标签: scala

我理解

  • 在Scala中应该避免使用null
  • 和Map.get将返回一个Option [B],我可以使用.getOrElse来获取值并回退到默认值

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 [A​​ny],我需要一个来自该键的字符串)

getOrElseNoNull(map,"key1","").asInstanceOf[String])

是否可以使用隐式扩展地图或任何其他优雅方式?

5 个答案:

答案 0 :(得分:7)

如果你正在处理一个不可变的Map,最安全的做法是预先过滤掉所有的null值(这会导致另一个Map实例的创建,但除非你有特别的理由要关心这里的表现应该不是问题。)

strlen

任何持有null的键都消失了,因此此键上的val withoutNulls = map.filter{case (k,v)=> v != null} 将返回getOrElse。 琐碎,并为所有人做了一次工作。

答案 1 :(得分:4)

Implicit extension classes救援:

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