case class Key(x: Int, var y: Int)
val key = Key(1,2)
val someMap = Map(key -> (1,2))
val newKey = key
newKey.y = 3  
val newMap = someMap + (newKey -> (1,3))
println(newMap(key))
What will be printed into the console?
Explanation
You just broke its equality and hashCode operation.
Case classes are syntactic sugar for defining classes in which - all constructor arguments are public and immutable and thus part of the value's identity, have structural equality, a corresponding hashCode implementation and apply/unapply auto-generated functions provided by the compiler.
As a general rule of thumb, structural equality only works for immutable things, because the equality operation must be stable (and not change according to the object's history). Case classes are for strictly immutable things. If you need to mutate stuff, don't use case classes.
Theory
  • Case classes are syntactic sugar for defining classes in which - all constructor arguments are public and immutable and thus part of the value's identity, have structural equality, a corresponding hashCode implementation and apply/unapply auto-generated functions provided by the compiler.
    By doing this:
    case class Sample(str: String, var number: Int)
    You just broke its equality and hashCode operation. Now try using it as a key in a map.
    As a general rule of thumb, structural equality only works for immutable things, because the equality operation must be stable (and not change according to the object's history). Case classes are for strictly immutable things. If you need to mutate stuff, don't use case classes.
    "The Joy of Clojure": if any two mutable objects resolve as being equal now, then there’s no guarantee that they will a moment from now.
    And if two objects aren’t equal forever, then they’re technically never equal ;-)

Follow CodeGalaxy

Mobile Beta

Get it on Google Play
Send Feedback
Cosmo
Sign Up Now
or Subscribe for future quizzes