2016-11-21 103 views
0

我有以下條件優化映射包含

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

凡地圖定義爲Map[Clazz,String]

Clazz被定義爲

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

然而,key字段單獨標識對象,所以field1和field2的比較是多餘的。如何優化contains聲明?

回答

4

簡單和直接的方式,而不是重寫的equals和hashCode

重新定義你的Clazz像下面。

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

這種方式等於和hashCode方法將生成只考慮密鑰和field1,field2將被忽略平等檢查。

這意味着密鑰唯一確定了您想要的clazz實例。

現在你可以做contains檢查哪些只會使用key進行內部平等檢查。

斯卡拉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 
} 

第三種方式是最不推薦的方式

只是保持Map[String, Clazz] Cla的關鍵zz地圖。

現在可以檢查包含像下面

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

keyMap.contains(clazz.key) 

如果匹配成功,那麼你可以使用代碼獲取的價值。

map.get(keyMap(clazz.key)) //this will give Option[String] 
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 
} 
+0

你可以,但它是一個可怕的想法。案例類通常被解釋爲(不可變的)值類型。這並不明顯,除非你去看看它的實現,它們實際上不是價值類型(DDD),而是實體。 –

+0

我明白你的意思,但我認爲它非常依賴於域名。如果在OP的領域這種平等並不奇怪,那麼它應該沒問題 –