4

I have a very basic equality check between two objects but it fails.

package foo
import org.junit.Assert._

object Sandbox extends App{
  class A

  val a = new A
  val b = new A
  assertEquals(a, b)

}

My use-case is more complex but I wanted to get my basics right. I get an assertion error when I run the code:

Caused by: java.lang.AssertionError: expected:<foo.Sandbox$A@3f86d38b> but was:<foo.Sandbox$A@206d63fd>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:144)
. . . . 

How can I compare two objects for equality?

Core_Dumped
  • 4,577
  • 11
  • 47
  • 71
  • possible duplicate of [Scala, Java and equality](http://stackoverflow.com/questions/3422669/scala-java-and-equality) – johanandren Feb 10 '15 at 08:22

2 Answers2

5
  1. You can override AnyRef equals function (the same way as you would need to override Object.equals in Java)

    def equals(arg0: Any): Boolean
    
  2. Or you can make A case class, Scala generates correct equals for case classes out of the box.

mavarazy
  • 7,562
  • 1
  • 34
  • 60
5

Unfortunately java defined an equals a hashCode and a toString method on every object. The default implementation of equals is to check referential equality, that is that they check that you are referring to the exact same object. Since you created two different objects, and gave no equals method to A they are not equal, since they aren't the same instance.

You can provide A with a better equals method, but anytime you override equals you should override hashCode as well to ensure that they two are in agreement. The rules for them being in agreement are:

  • if equals returns true, the two objects must return the same hashCode
  • if objects have different hashCodes, equals must return false.
stew
  • 11,276
  • 36
  • 49