优化地图包含

时间:2016-11-21 13:21:46

标签: scala

我有以下条件

if (map.contains(clazz)) {
      // .....
}

将地图定义为Map[Clazz,String]

Clazz定义为

case class Clazz(key: String, field1: String, field2: String)

但是,仅key字段标识对象,因此field1和field2的比较是多余的。如何优化contains语句?

2 个答案:

答案 0 :(得分:4)

简单直接的方式,而不是覆盖equals和hashCode

重新定义您的Clazz,如下所示。

case class Clazz(key: String)(field1: String, field2: String)

这样生成equals和hashCode方法时只考虑密钥和field1,对于等式检查,将忽略field2。

这意味着密钥唯一地确定了你想要的clazz实例。

现在你可以contains检查哪个只会在内部使用key进行相等检查。

Scala REPL

scala> case class Clazz(key: String)(field1: String, field2: String)
defined class Clazz

scala> val map = Map(Clazz("foo")("apple", "ball") -> "foo", Clazz("bar")("cat", "bat") -> "bar")
map: Map[Clazz, String] = Map(Clazz(foo) -> "foo", Clazz(bar) -> "bar")

scala> map contains Clazz("foo")("moo", "zoo")
res2: Boolean = true

scala> map contains Clazz("bar")("moo", "zoo")
res3: Boolean = true

scala> map contains Clazz("boo")("moo", "zoo")
res4: Boolean = false

其他方式是覆盖equals和hashCode

case class Clazz(key: String, field1: String, field2: String) {
  override def equals(otherClazz: Any) = that match {
    case otherClazz: Clazz => otherClazz.key.equals(key)
    case _ => false
  }
  override def hashCode = key.hashCode
}

第三种方式是最不推荐的方式

只需保留Clazz地图的Map[String, Clazz]键即可。

现在您可以查看以下内容

val keyMap = map.map { case (clazz, _) => clazz.key -> clazz}

keyMap.contains(clazz.key)

当匹配成功时,您可以使用代码获取值。

map.get(keyMap(clazz.key)) //this will give Option[String]

答案 1 :(得分:2)

您可以重新定义equalshashCode

case class Clazz(key: String, field1: String, field2: String) {
  override def equals(that: Any) = that match {
    case that: Clazz => that.key.equals(key)
    case _ => false
  }
  override def hashCode = key.hashCode
}