Having equals() and hashCode() at the same time and in consistent is important when objects are used as keys in collections. I remember that we ran into issues in CloudStack a long time ago when some of these basic rules were broken
Kelven On 2/25/14, 3:13 PM, "Mike Tutkowski" <mike.tutkow...@solidfire.com> wrote: >This is a good summary of the equals and hashCode methods: > > > 1. If object1 and object2 are equal according to their equals() method, > they must also have the same hash code. > 2. If object1 and object2 have the same hash code, they do NOT have to > be equal too. > >From http://tutorials.jenkov.com/java-collections/hashcode-equals.html > > >On Tue, Feb 25, 2014 at 3:07 PM, Marcus <shadow...@gmail.com> wrote: > >> Also keep in mind that with an Object or custom objects that extend it, >> doing >> >> if (obj.equals(thing)) >> >> is usually the same as: >> >> if (obj == thing) >> >> Since the Object.equals() method by default says something like: >> >> public boolean equals(Object other) >> { >> return this == other; >> } >> >> Unless it is overridden, (along with hashCode() from what I >> understand, since Objects deemed 'equal' are supposed to return the >> same hash). So the issue may partially be due to the fact that those >> are largely equivalent in many objects, but not in objects like >> Integer which presumably do something different in their equals() >> implementation. When something works as expected in other >> circumstances it's understandable that the mistake would be made. >> >> I actually fixed a bug recently with resource tags that dealt with >> this, a listVirtualMachines call would duplicate the resource tags, >> sometimes printing up to 8 of the same tag, because someone had done >> "if(!tag1.equals(tag2))", or something expecting to filter duplicates. >> To fix I just implemented the equals() and hashCode() for the resource >> tag object. >> >> >> On Tue, Feb 25, 2014 at 12:19 PM, Suresh Sadhu <suresh.sa...@citrix.com> >> wrote: >> > Thanks Hugo for sharing this valuable info. >> > >> > And also it provides "Different" output when value crosses the Int >> range >> > >> > public class App >> > { >> > public static void main(String[] args) >> > { >> > Integer a = 128; >> > Integer b = 128; >> > >> > if (a == b) { >> > System.out.println("Equal!"); >> > } else { >> > System.out.println("Different!"); >> > } >> > } >> > } >> > >> > Output:Different. >> > >> > Regards >> > Sadhu >> > >> > >> > >> > >> > -----Original Message----- >> > From: Min Chen [mailto:min.c...@citrix.com] >> > Sent: 25 February 2014 23:08 >> > To: dev@cloudstack.apache.org >> > Subject: Re: Anti-patterns >> > >> > Thanks Hugo for the nice tutorial. In the last example, are you trying >> to saying this (luckily this time == works although not recommended) >> > >> > public class App >> > { >> > public static void main(String[] args) >> > { >> > Integer a = 1; >> > Integer b = 1; >> > >> > if (a == b) { >> > System.out.println("Equal!"); >> > } else { >> > System.out.println("Different!"); >> > } >> > } >> > } >> > >> > -min >> > >> > >> > >> > >> > On 2/25/14 5:41 AM, "Hugo Trippaers" <h...@trippaers.nl> wrote: >> > >> >>Anti-pattern: >> >>An anti-pattern (or antipattern) is a common response to a recurring >> >>problem that is usually ineffective and risks being highly >> >>counterproductive. The term, coined in 1995 by Andrew Koenig, was >> >>inspired by a book, Design Patterns, in which the authors highlighted >>a >> >>number of design patterns in software development that they considered >> >>to be highly reliable and effective. >> >>< source http://en.wikipedia.org/wiki/Anti-pattern >> >> >> >> >> >>Here at Schuberg we spend quite some time going through bugs reports >> >>from automated scanners, you have probably seen the mails coming by on >> the ML. >> >>As part of our work we have encountered a number of problems that keep >> >>on popping up in the code base. So here is my first attempt to clarify >> >>why a certain pattern is wrong and hopefully help developers to avoid >> this. >> >> >> >>So first up is the equality operator, ==. This operator is commonly >> >>used in many languages to compare if two items are equal. The trick >> >>with this operator in java is to know exactly what you are comparing, >> >>because it matters. >> >> >> >>Consider this piece of code: >> >> >> >>public class App >> >>{ >> >> public static void main(String[] args) >> >> { >> >> int a = 1; >> >> int b = 1; >> >> >> >> if (a == b) { >> >> System.out.println("Equal!"); >> >> } else { >> >> System.out.println("Different!"); >> >> } >> >> } >> >>} >> >> >> >>The expected outcome is ³Equal!² and indeed it prints just that. Now >> >>consider the following code: >> >> >> >>public class App >> >>{ >> >> public static void main(String[] args) >> >> { >> >> Integer a = new Integer(1); >> >> Integer b = new Integer(1); >> >> >> >> if (a == b) { >> >> System.out.println("Equal!"); >> >> } else { >> >> System.out.println("Different!"); >> >> } >> >> } >> >>} >> >> >> >>The result of running this bit of code is ³Different!². With == you >>are >> >>telling the java compiler to compare the two variables. The variable >> >>are references to Objects, so it will do exactly what you tell it to >> >>do, compare the two object references. As you give it two different >> >>objects, the result willl be ³Different!². The correct way of >>comparing >> >>the contents of two objects is to use the equals method. Consider the >> >>following piece of code: >> >> >> >>public class App >> >>{ >> >> public static void main(String[] args) >> >> { >> >> Integer a = new Integer(1); >> >> Integer b = new Integer(1); >> >> >> >> if (a.equals(b)) { >> >> System.out.println("Equal!"); >> >> } else { >> >> System.out.println("Different!"); >> >> } >> >> } >> >>} >> >> >> >> >> >>This will again be ³Equals!². >> >> >> >>Why is this often a problem? There are a lot or reasons why these bugs >> >>came to exist in CloudStack (or any other project). For example >> >>somebody might cause this bug by changing the return type of a >>function >> >>from long to Long. The first one is a primitive which can be compared >> >>with == and the second one is an Object which might result in another >> >>comparison than you intended. Findbugs will catch these types of >> >>comparisons and warn you for them. See commit >> >>d1efdca50622a0b67ae1a286aad3297b1c748e9e for an example. >> >> >> >> >> >> >> >>Oh and what does this print? >> >> >> >>public class App >> >>{ >> >> public static void main(String[] args) >> >> { >> >> Integer a = 1; >> >> Integer b = 1; >> >> >> >> if (a.equals(b)) { >> >> System.out.println("Equal!"); >> >> } else { >> >> System.out.println("Different!"); >> >> } >> >> } >> >>} >> >> >> >> >> >>Surprise!, it prints ³Equals!². This is a boxed integer and java >>keeps >> >>a pool of these so internally the object is cached and both a and b >>get >> >>the same objects assigned to them by the internal boxing logic. Just >> >>never rely on this! It only works in specific cases and is >> >>implementation specific per JVM vendor and JVM version. >> >> >> >>Cheers, >> >> >> >>Hugo >> >> >> >> >> >>P.S. If you have another anti pattern feel free to post em in this >> thread. >> >> >> > >> > > > >-- >*Mike Tutkowski* >*Senior CloudStack Developer, SolidFire Inc.* >e: mike.tutkow...@solidfire.com >o: 303.746.7302 >Advancing the way the world uses the >cloud<http://solidfire.com/solution/overview/?video=play> >*(tm)*