Java developers will inevitably come across Scala at some point and say something like, “This is merely a simpler Java, with better functional support.”
Au contraire, my dear Java developer. There are far too many fundamental differences between Java and Scala for that statement to ever make sense. Take, for consideration, the simple matter of equality.
Java equality with “==” is unintuitive. It is littered with inconsistencies. Primitives are compared always by value. Objects are almost always compared by reference. Thus you have:
int x = 1; int y = 1; System.out.println(x == y); //prints true Integer xObj = new Integer(1); Integer yObj = new Integer(1); System.out.println(xObj == yObj); //prints false
Furthermore, Java’s designers decided String instances should be interned which is a fancy way of saying the JVM caches instances of Strings so they can be reused. Thus, if you attempt to create a second new String instance with the same contents as one previously created, the JVM usually returns the previous instance again.
Therefore, you get the now-unexpected behavior that String objects evaluate true for an “==” comparison.
String s = "Hello"; String t = "Hello"; System.out.println(s == t); //prints true
In other words, Java equality sucks.
Scala equality, on the other hand, is straightforward. There are no primitives in Scala. Everything is an object. It has one unified type system, and doesn’t need anything else. The same comparisons that were confusing in Java will behave as expected in Scala.
An example REPL output:
scala> val x = 1 x: Int = 1 scala> val y = 1 y: Int = 1 scala> x == y res5: Boolean = true scala> val s = "Hello" s: String = Hello scala> val t = "Hello" t: String = Hello scala> s == t res7: Boolean = true
Even using Java types in Scala, you will see the new behavior:
scala> new java.lang.Integer(1) res0: Integer = 1 scala> new java.lang.Integer(1) res1: Integer = 1 scala> res0 == res1 res2: Boolean = true
Generally the “==” operator compares by value in Scala. For reference equality, the method “eq” can be used. It also has a negation “ne”. Both are inherited from the AnyRef superclass.
scala> val scott = new Person("Scott") scott: Person = Person(Scott) scala> val scott2 = new Person("Scott") scott2: Person = Person(Scott) scala> scott == scott2 res11: Boolean = true scala> scott eq scott2 res12: Boolean = false scala> scott ne scott2 res13: Boolean = true
There is one similarity, though. Strings in Scala are still interned, as in Java, so “eq” will return true usually for two String instances containing the same value.
scala> val s = "Hello" s: String = Hello scala> val t = "Hello" t: String = Hello scala> s eq t res8: Boolean = true