10
scala> List(1,2,3) == List(1,2,3)

res2: Boolean = true

scala> Map(1 -> "Olle") == Map(1 -> "Olle")

res3: Boolean = true

But when trying to do the same with Array, it does not work the same. Why?

scala> Array('a','b') == Array('a','b')

res4: Boolean = false

I have used 2.8.0.RC7 and 2.8.0.Beta1-prerelease.

Johnny
  • 14,397
  • 15
  • 77
  • 118
olle kullberg
  • 6,249
  • 2
  • 20
  • 31
  • 1
    Note: You can search for all scala related array questions with [scala] [array] – oluies Jul 09 '10 at 18:44
  • possible duplicate of [Why does \`Array(0,1,2) == Array(0,1,2)\` not return the expected result?](http://stackoverflow.com/questions/2481149/why-does-array0-1-2-array0-1-2-not-return-the-expected-result) – Suma Jan 21 '15 at 19:53

2 Answers2

19

Because the definition of "equals" for Arrays is that they refer to the same array.

This is consistent with Java's array equality, using Object.Equals, so it compares references.

If you want to check pairwise elements, then use sameElements

Array('a','b').sameElements(Array('a','b'))

or deepEquals, which has been deprecated in 2.8, so instead use:

Array('a','b').deep.equals(Array('a','b').deep)

There's a good Nabble discussion on array equality.

Stephen
  • 47,994
  • 7
  • 61
  • 70
  • 2
    Is Array the only exception to the general rule of comparing the actual elements for the built in collections? All other collections I have tried compare the elements. – olle kullberg Jul 09 '10 at 17:03
  • 2
    @olle - as far as I know, it is the only collection that exhibits this behavior. Even `ArrayList` compares elements. What I can't figure out, is how this is supposed to be learned from the documentation :) – Stephen Jul 09 '10 at 18:10
  • 3
    also see http://stackoverflow.com/questions/2481149/why-does-array0-1-2-array0-1-2-not-return-the-expected-result – oluies Jul 09 '10 at 18:44
  • 5
    @olle : The java array _is_ an object ( http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html , especially section 10.8) `WrappedArray` wraps the java array in a class. `Array` _is_ the java array. The reason it can't override `Object.equals` (and provide a specialized equals) is because it does not subclass the java array. If it wrapped array, or subclassed it, it would behave as you expected. Gotta say, my answer is entirely accurate, except for not going into detail about _why_ it can't override the behavior. – Stephen Jul 10 '10 at 15:53
  • 1
    @olle : BTW, Your explanation is factually incorrect when you say "the correct explanation ..." If you don't accept it, fine, but the -1 is adding insult to injury! :) – Stephen Jul 10 '10 at 15:56
  • 1
    My bad, you are correct! I've read in "Beyond Java" (B. Tate) that the Java array is not an object, but just as you said, this is not true. – olle kullberg Jul 12 '10 at 07:03
  • 1
    @olle : Thanks for clearing that up. And I'll be staying away from that book :) – Stephen Jul 12 '10 at 15:30
2

The root cause the it is that fact that Scala use the same Array implementation as Java, and that's the only collection that not support == as equality operator.

Also, it's important to note that the chosen answer suggest equally sameElements and deep comparison when actually it's preferred to use:

Array('a','b').deep.equals(Array('a','b').deep)

Or, because now we can use == back again:

Array('a','b').deep == Array('a','b').deep

Instead of:

Array('a','b').sameElements(Array('a','b'))

Because sameElements won't for for nested array, it's not recursive. And deep comparison will.

Johnny
  • 14,397
  • 15
  • 77
  • 118