Examples:
// Language: JAVA // expected cases assert 3 == 3 // basic equality assert 4L == 4 // long integer equals integer version // equality on reference 1 // A is a class that does not overload the equals method A a1 = new A(3); A a2 = new A(3); assert a1 != a2; // there are two different objects so they are different assert !a1.equals(a2); // the equals method is not overloaded, so the basic reference is used by the JVM A a3 = a1; // we put the reference to a1 in a3 assert a1 == a3; // now the reference are the same assert a1.equals(a3); // same as before the equals is not overloaded so the reference are used // B is a class that overload equals method, so that the method compares the internal value directly B b1 = new B(1); B b2 = new B(2); B b3 = new B(1); assert b1 != b2; // the references are still different assert b1 != b3; assert !b1.equals(b2); // the equals method is used, so we compare their internal value, '1' with '2' assert b1.equals(b3); // this is true because '1' == '1' // third part: the strings, in Java the string are stored natively in memory // and the String object have reference to the intern memory, // so the equals is quite the same as '==' String str1 = "hello world"; String str2 = "hello you"; String str3 = "hello world"; String str4 = "hell" + "o world"; // concatenation of strings resulting in the same string value assert str1 != str2; assert str1 == str3; assert str1 == str4;1 : String equality, Advance reference
This is what we expect in Java, not necessarily in other languages and that is the problem when we start with Groovy.
Grooy truth:
// Language: GROOVY // like before assert 3 == 3 assert 4L = 4 // but in groovy the equals is replace by == and == by "is" operator // for class that does not implement equals it's quite the same as Java // class that does not overload equals A a1 = new A(3) A a2 = new A(4) assert a1 != a2 // internally groovy use a1.equals(a2) assert !a1.is(a2) // the '==' equivalent of Java // class that overload equals method B b1 = new B(3) B b2 = new B(4) B b3 = new B(3) // same value B b4 = b1 // same reference // here the things get more normal for a non-Java developper assert b1 != b2 assert b1 == b3 // use equals, so compare internally the value assert b1 == b4 // the reference are the same, so the equals returns true assert !b1.is(b3) assert b1.is(b4) // same reference // the strings come back to normal behavior not like Java with its static memory table to store Strings value assert "hello world" == "hello world" assert "hello you" != "hello me" // ready for weirdest thing in Groovy ? // Let's go, when a class implements Comparable in Groovy, // the == is no more the method equals, but now, the compareTo that should return 0 ! // C is a class that implements Comparable and overload equals // compare method use the first value and the equals method the second C c1 = new C(3, 5) C c2 = new C(2, 5) C c3 = new C(3, 6) assert c1.equals(c2) // the second values are the same, 5 == 5 assert !c1.equals(c3) // 5 != 6 assert c1 != c2 // compare 3 and 2 => not 0 assert c1 == c3 // compare 3 and 3 If you are not aware of this, we would have lots of bug without knowing the source because it's hidden, so don't forget to be consistant between equals / compareToHere is the source code for the A, B, C classes, in groovy:
// Language: GROOVY
class A {
int val
A(int _val){
this.val = _val
}
}
class B {
int val
B(int _val){
this.val = _val
}
@Override
public boolean equals(Object obj) {
if(obj instanceof B){
B that = (C) obj
if(this.val == that.val){
return true
}
}
return false
}
}
class C implements Comparable<C>{
int valEqual
int valComparable
C(int _valComparable, int _valEqual){
this.valEqual = _valEqual
this.valComparable = _valComparable
}
@Override
public boolean equals(Object obj) {
if(obj instanceof C){
C that = (C) obj
if(this.valEqual == that.valEqual){
return true
}
}
return false
}
@Override
public int compareTo(C that) {
// <=> is a special groovy operator that replace .compareTo method
// in this case we use to compare integer with the normal compareTo method
return this.valComparable <=> that.valComparable
}
}
Hope that will help you avoiding errors and understand the real Groovy Truth !
No comments:
Post a Comment