|
Am I missing something totally obvious, or are arrays never equal?
=============================== Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0). Type in expressions to have them evaluated. Type :help for more information. scala> Array(1) == Array(1) res0: Boolean = false scala> Array(1) eq Array(1) res1: Boolean = false scala> Array(1) === Array(1) <console>:5: error: value === is not a member of Array[Int] Array(1) === Array(1) ^ scala> Array(1) equals Array(1) res3: Boolean = false |
|
FFT wrote:
> Am I missing something totally obvious, or are arrays never equal? > > =============================== > > Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0). > Type in expressions to have them evaluated. > Type :help for more information. > > scala> Array(1) == Array(1) > res0: Boolean = false > > scala> Array(1) eq Array(1) > res1: Boolean = false > > scala> Array(1) === Array(1) > <console>:5: error: value === is not a member of Array[Int] > Array(1) === Array(1) > ^ > > scala> Array(1) equals Array(1) > res3: Boolean = false > > produces false, since the implementation compares reference values for array types. Alternatively, you can use the sameElements method or if you have Scalaz and want more flexibility, there is a === method which uses implicits to look up the strategy to test for equality. -- Tony Morris http://tmorris.net/ |
|
In reply to this post by fft1976
By the way, I understand that some of the equalities are reference
equalities and others are supposedly structural equalities, but here all of ==, eq and equals return "false", whereas for Lists == and equals return "true". Is this an oversight? On Mon, Apr 20, 2009 at 9:41 PM, FFT <[hidden email]> wrote: > Am I missing something totally obvious, or are arrays never equal? > > =============================== > > Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0). > Type in expressions to have them evaluated. > Type :help for more information. > > scala> Array(1) == Array(1) > res0: Boolean = false > > scala> Array(1) eq Array(1) > res1: Boolean = false > > scala> Array(1) === Array(1) > <console>:5: error: value === is not a member of Array[Int] > Array(1) === Array(1) > ^ > > scala> Array(1) equals Array(1) > res3: Boolean = false > |
|
FFT wrote:
> By the way, I understand that some of the equalities are reference > equalities and others are supposedly structural equalities, but here > all of ==, eq and equals return "false", whereas for Lists == and > equals return "true". Is this an oversight? > > On Mon, Apr 20, 2009 at 9:41 PM, FFT <[hidden email]> wrote: > >> Am I missing something totally obvious, or are arrays never equal? >> >> =============================== >> >> Welcome to Scala version 2.7.3.final (OpenJDK Client VM, Java 1.6.0_0). >> Type in expressions to have them evaluated. >> Type :help for more information. >> >> scala> Array(1) == Array(1) >> res0: Boolean = false >> >> scala> Array(1) eq Array(1) >> res1: Boolean = false >> >> scala> Array(1) === Array(1) >> <console>:5: error: value === is not a member of Array[Int] >> Array(1) === Array(1) >> ^ >> >> scala> Array(1) equals Array(1) >> res3: Boolean = false >> >> > > class T { public static void main(String[] args) { final String[] x = new String[] { "a", "b", "c" }; final String[] y = new String[] { "a", "b", "c" }; System.out.println(x == y); // false System.out.println(x.equals(y)); // false } } To use === you'll need Scalaz which is third-party. -- Tony Morris http://tmorris.net/ |
|
On Mon, Apr 20, 2009 at 11:33 PM, Tony Morris <[hidden email]> wrote:
> No it is not an oversight -- any more than it is for Java anyway. java.util.ArrayList though works as I would expect, as does java.util.Arrays.equals. |
|
FFT wrote:
> On Mon, Apr 20, 2009 at 11:33 PM, Tony Morris <[hidden email]> wrote: > > >> No it is not an oversight -- any more than it is for Java anyway. >> > > java.util.ArrayList though works as I would expect, as does > java.util.Arrays.equals. > > Scala, you'd get the same result you get in Java -- just the same as you did when using ==. When you're using == you're calling Java's Object.equals method, which behaves exactly as it would in Java. If any oversight exists, it does so in the API of Java. -- Tony Morris http://tmorris.net/ |
|
In reply to this post by Tony Morris
== is the same as equals, is not it? eq is referential equality.
Arrays in Java, traditionally, don't have a reasonable equals method.
2009/4/20 Tony Morris <[hidden email]>
-- Thanks, -Vlad |
|
Vlad Patryshev wrote:
> == is the same as equals, is not it? eq is referential equality. > > Arrays in Java, traditionally, don't have a reasonable equals method. Since arrays are mutable I think it's a very reasonable equals method. /Jesper Nordenberg |
|
On Tue, Apr 21, 2009 at 12:28 AM, Jesper Nordenberg <[hidden email]> wrote:
> Vlad Patryshev wrote: >> >> == is the same as equals, is not it? eq is referential equality. In Java: new Integer(1) == new Integer(1); // false (new Integer(1)).equals(new Integer(1)); // true >> Arrays in Java, traditionally, don't have a reasonable equals method. > > Since arrays are mutable I think it's a very reasonable equals method. Doesn't seem consistent with, say, Integer or ArrayList classes. I think it would be reasonable to reserve at least one of the many equalities to mean the equality of contents, but I may be bringing my prejudices with me. |
|
FFT wrote:
> On Tue, Apr 21, 2009 at 12:28 AM, Jesper Nordenberg <[hidden email]> wrote: > >> Vlad Patryshev wrote: >> >>> == is the same as equals, is not it? eq is referential equality. >>> > > In Java: > > new Integer(1) == new Integer(1); // false > (new Integer(1)).equals(new Integer(1)); // true > -- Tony Morris http://tmorris.net/ |
|
In reply to this post by fft1976
Hi FFT,
There are numerous definitions of equality. For many purposes it is a good idea for x == y to be constant for the life of x and the life of y. Array(1) == Array(1) breaks this, as arrays can be mutated. List(1) == List(1) doesn't, as Lists cannot be mutated. Equality is an interesting topic, merely because of the incredible range of interpretations there are of it. Cheers, Ricky. 2009/4/21 FFT <[hidden email]> Am I missing something totally obvious, or are arrays never equal? |
|
In reply to this post by fft1976
FFT wrote:
> Doesn't seem consistent with, say, Integer or ArrayList classes. Integer is an immutable class so that's fine. As for ArrayList I think it's a mistake, probably stemming from the fact that there are no immutable collection classes in the Java libraries (you can create a dynamically checked read-only ArrayList). > I think it would be reasonable to reserve at least one of the many > equalities to mean the equality of contents, but I may be bringing my > prejudices with me. Equals should mean equality of content for immutable value types. But for references to mutable objects my opinion is that they should never be equal unless they reference the same object, otherwise it's impossible to for example implement a useful hashCode() method. Sure you can add another method that performs time variant content equality checks. /Jesper Nordenberg |
|
On Tue, Apr 21, 2009 at 1:30 AM, Jesper Nordenberg <[hidden email]> wrote:
> Equals should mean equality of content for immutable value types. But for > references to mutable objects my opinion is that they should never be equal > unless they reference the same object, otherwise it's impossible to for > example implement a useful hashCode() method. Why isn't hashCode() similarly crippled or disabled for mutable data structures? Wouldn't that make just as much sense? > Sure you can add another method that performs time variant content equality checks. Can I do that without boilerplate in every class definition? |
|
Why isn't hashCode defined in a Hashable interface?
Why isn't it possible to define code-contracts for abstract methods/interface methods? :( On Tue, Apr 21, 2009 at 11:50 AM, FFT <[hidden email]> wrote:
-- Viktor Klang Senior Systems Analyst |
|
Viktor Klang wrote:
> Why isn't hashCode defined in a Hashable interface? http://functionaljava.googlecode.com/svn/artifacts/latest/javadoc/fj/pre/Hash.html -- Tony Morris http://tmorris.net/ |
|
Is this yet another case of great minds thinking alike? ;)
On Tue, Apr 21, 2009 at 12:50 PM, Tony Morris <[hidden email]> wrote:
-- Viktor Klang Senior Systems Analyst |
|
In reply to this post by fft1976
FFT wrote:
> Why isn't hashCode() similarly crippled or disabled for mutable data > structures? Wouldn't that make just as much sense? I didn't mean to imply that equals() is crippled for mutable objects, it's perfectly useful. Similarly the default implementation of Object.hashCode() is perfectly useful for mutable objects, it always returns the same hash for an object but still provide a good distribution over the integers. >> Sure you can add another method that performs time variant content equality checks. > > Can I do that without boilerplate in every class definition? Yes, you can "hack" case classes to make this work: scala> trait MutableProduct extends Product { override def equals(v : Any) = super.equals(v); override def hashCode = super.hashCode } defined trait MutableProduct scala> case class P(var i : Int) extends MutableProduct defined class P scala> P(1) == P(1) res33: Boolean = false Every case class in Scala implements Product, so you can write a generic deep comparison function which will work with all case classes as well: scala> def equalElements(v1 : Any, v2 : Any) : Boolean = (v1, v2) match { case (m1 : MutableProduct, m2 : MutableProduct) => m1.getClass == m2.getClass && (0 until m1.productArity).forall(i => equalElements(m1.productElement(i), m2.productElement(i))) case _ => v1 == v2 } equalElements: (Any,Any)Boolean scala> equalElements(P(1), P(1)) res42: Boolean = true (Note that the code might be buggy) /Jesper Nordenberg |
|
On Tue, Apr 21, 2009 at 7:08 AM, Jesper Nordenberg <[hidden email]> wrote:
> Yes, you can "hack" case classes to make this work: > Nice... > Every case class in Scala implements Product, so you can write a generic > deep comparison function which will work with all case classes as well: Why doesn't Programming In Scala talk about this? At least Product isn't mentioned in the index. > m1.getClass == m2.getClass && Is this much slower than boilerplaty manual version would be (reflection)? |
|
FFT wrote:
>> Every case class in Scala implements Product, so you can write a generic >> deep comparison function which will work with all case classes as well: > > Why doesn't Programming In Scala talk about this? At least Product > isn't mentioned in the index. I have no idea. Product is a useful trait for dynamically decomposing a case class. >> m1.getClass == m2.getClass && > > Is this much slower than boilerplaty manual version would be (reflection)? I except the Object.getClass() method to be very fast, it's typically used when overriding equals(). /Jesper Nordenberg |
|
"I except the Object.getClass() method to be very fast, it's typically used when overriding equals()."
How do you use getClass in an equals implementation without violating the equals contract? 2009/4/22 Jesper Nordenberg <[hidden email]>
|
| Powered by Nabble | Edit this page |
