Is it possible to ignore a field of a case class in the equals/haschode method of the case class?
My use case is that I have a field that is essentially metadata for rest of the data in the class.
Only parameters in the first parameter section are considered for equality and hashing.
scala> case class Foo(a: Int)(b: Int)
defined class Foo
scala> Foo(0)(0) == Foo(0)(1)
res0: Boolean = true
scala> Seq(0, 1).map(Foo(0)(_).hashCode)
res1: Seq[Int] = List(-1669410282, -1669410282)
UPDATE
To expose b
as a field:
scala> case class Foo(a: Int)(val b: Int)
defined class Foo
scala> Foo(0)(1).b
res3: Int = 1
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Foo private(x: Int, y: Int) {
def fieldToIgnore: Int = 0
}
object Foo {
def apply(x: Int, y: Int, f: Int): Foo = new Foo(x, y) {
override lazy val fieldToIgnore: Int = f
}
}
// Exiting paste mode, now interpreting.
defined class Foo
defined module Foo
scala> val f1 = Foo(2, 3, 11)
f1: Foo = Foo(2,3)
scala> val f2 = Foo(2, 3, 5)
f2: Foo = Foo(2,3)
scala> f1 == f2
res45: Boolean = true
scala> f1.## == f2.##
res46: Boolean = true
You may override .toString
if necessary.
You can override the equals and hasCode methods in a case class
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Person( val name:String, val addr:String) {
override def equals( arg:Any) = arg match {
case Person(s, _) => s == name
case _ => false
}
override def hashCode() = name.hashCode
}
// Exiting paste mode, now interpreting.
scala> Person("Andy", "") == Person("Andy", "XXX")
res2: Boolean = true
scala> Person("Andy", "") == Person("Bob", "XXX")
res3: Boolean = false
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With