私のScalaバージョンは2.11.8
で、Javaバージョンは1.8.0_77
です。Scala:なぜマップと不変マップが同じカスタムクラスインスタンス上でキーと異なる結果になるのですか?
私はカスタムクラスを持っていましたV
はOrdered[V]
です。カスタムcompare
とequals
を定義しました。私はV
インスタンスが>
、<
、>=
、<=
の演算子を持ち、それらの特定の属性が等しいときに等しいと考えることができます。ここで
は私のプロジェクトから抽出された単純化されたコードです:
class V(val value: Int, val score: Int = 0) extends Ordered[V] {
def compare(that: V): Int = this.score compare that.score
override def equals(that: Any): Boolean = that match {
case that: V => this.value == that.value
case _ => false
}
}
val a = new V(1, 2)
val b = new V(1, 3)
// return true because a.value == b.value
a == b
そして奇妙:
import collection.mutable.ArrayBuffer
val mm = collection.mutable.Map(a -> ArrayBuffer(0, 1), b -> ArrayBuffer(2, 3, 4))
val im = collection.immutable.Map(a -> ArrayBuffer(0, 1), b -> ArrayBuffer(2, 3, 4))
// return scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()
mm.getOrElse(new V(1, 0), ArrayBuffer())
// return scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 3, 4)
im.getOrElse(new V(1, 0), ArrayBuffer())
immutable.Map
とmutable.Map
の結果が異なっているのはなぜ?
しかし、私はV
ためhashCode
定義する場合:
class V(val value: Int, val score: Int = 0) extends Ordered[V] {
def compare(that: V): Int = this.score compare that.score
override def hashCode: Int = value // new method here!
override def equals(that: Any): Boolean = that match {
case that: V => this.value == that.value
case _ => false
}
}
val a = new V(1, 2)
val b = new V(1, 3)
a == b // true
そして、この時間は、結果は同じです。
val mm = collection.mutable.Map(a -> ArrayBuffer(0, 1), b -> ArrayBuffer(2, 3, 4))
val im = collection.immutable.Map(a -> ArrayBuffer(0, 1), b -> ArrayBuffer(2, 3, 4))
// both return scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(2, 3, 4)
mm.getOrElse(new V(1, 0), ArrayBuffer())
im.getOrElse(new V(1, 0), ArrayBuffer())
なぜhashCode
定義は、カスタムクラスのインスタンス上で変更可能な地図の結果に影響を与えませんキーとして?
驚くような答え!ありがとう!いくつかの新しい質問は、 'Map1'の' get'の実装に基づいて '不変です。Map'は 'Map1'(または' Map2'、 'Map3'、' Map4')インスタンスのコレクションを使用してキー値を保存しますか? 1つの 'Map1'(または' Map2'、 'Map3'、' Map4')インスタンスは一つのキー値ですか?不変のMap内でいくつかのキーを検索すると、 'immutable.Map'は内部コレクション全体を反復して対応する値を見つけますか?すみません、私は 'immutable.Map'のソースコードを読んでいますが、どうやって処理するのか見つからなかったのですか、誤解がありますか? – user3295962
@ user3295962 'Map1'から' Map4'への 'Map1'は、あなたが渡す引数の数に応じて使用されます(Map(1 - > 1,2 - > 2)を実行すると、 Map2')。 'immutable.Map'に関して、それは間違いなくコレクション全体を反復しません。 'Map'の全体的な意味は、そのキーに基づいて値を一定の時間で検索することです。 –