Gleichheit und Identität in Scala sind wie in Java. Standardmäßig sind zwei Objekte nur dann identisch, wenn sie identisch sind. Eine Klasse muss equals
und hashCode
überschreiben, damit zwei verschiedene Objekte in Hashing-Daten als gleichwertig behandelt werden. Wenn diese Methoden nicht überschrieben werden, sind zwei beliebige Objekte nicht "gleich" und werden nicht als Hash-Schlüssel verwendet.
Der Hauptunterschied zwischen Java und Scala ist, dass der Operator ==
Gleichheit testet, d. H. Die equals
Methode verwendet, während in Java ==
Identität testet. (Um die Identität in Scala zu testen, verwenden Sie den Operator eq
.)
In Ihrem zweiten Codefragment ergibt also jede Auswertung von new Label("AB")
ein eindeutiges, nicht relevantes Objekt. Das Nachschlagen auf das Ergebnis der zweiten Auswertung kann nicht zur ersten ausgewertet werden.
In Scala viel mehr als Java jedoch ist die übliche Praxis, unveränderliche Objekte zu definieren, die equals
und hashCode
überschreiben. Scala bietet den Begriff "Fallklassen" an, die diese Methoden unter anderem automatisch überschreiben.
Sie können Ihr zweites Code-Snippet reparieren, indem Sie das Wort case
vor Ihre Klassendefinition für Label
setzen.
scala> import scala.collection.mutable
import scala.collection.mutable
scala> case class Label(val name: String) {
| override def toString = s"Label($name)"
| }
defined class Label
scala> object Main extends App {
| var map = mutable.Map[Label, Int]()
| map += new Label("AB") -> 1
| println(map(new Label("AB")))
| }
defined object Main
scala> Main.main(Array.empty[String])
1
Beachten Sie, dass Fallklassen auch automatisch für die Klasse eines Begleitobjekt definieren, und eine apply
Methode, die den Haupt-Konstruktor aufruft. Anstatt also new Label("AB")
zu schreiben, wäre es konventioneller, einfach Label("AB")
zu schreiben.
Duplikat von [wie-ist-Schlüssel-Äquivalenz-definiert-wann-verwenden-Scalas-hashmap] (http://stackoverflow.com/questions/10805570/how-is-key-equivalence-defined-when-using -scalas-hashmap) – Samar