Jumat, 09 Januari 2015

Why Override equals, hashcode and toString method in Java



Couple of questions, which are often asked to me was why do we need to override equals() and hashcode() method, Why should I implement toString(), What will happen if I don't override them or in a different way, I have never overridden equals and hashcode and not faced any problem, why should I override them now. You guessed it correct, almost all of these questions comes from beginners, who have either taken some Java programming classes, or started learning Java by their own. Though concept of equality is something you cannot ignore, correct understanding of equals(), hashcode(), toString() and some other method from java.lang.Object class, often goes unnoticed, at least until they self-realize it or Interviewer force them to explore that part. I have already written couple of articles on equals and hashcode, e.g. equals vs ==,  hashcode tips, equals and hashcode interview questions and one of my personal favorite, 5 tips to override equals in Java, which already touches this subject but I thought to explain it clearly here for once and all.








Why you should override equals or hashcode


From the face, you can guess that equals() is used to check if two objects are equal or not. Now this equality can be defined in two ways, identity equality and logical equality, as I explained in equals vs == post, it's the logical equality, which is taken care by equals method. If you are doing Java programming than you probably know that every class in Java implicitly inherit from java.lang.Object, and from there every object inherit equals() and hashcode(). There default implementation is in line with == operator, i.e. equals() provide identity equality and return true if reference variable pointing to same object. Now, if you don't need logical equality, then you don't need to override equals, but the problem is you will need it. All your domain object e.g. Order, Trade, Message can be compared to each other and you need logical comparison. One of the popular example is java.lang.String class, which needs logical comparison i.e. character based comparison. If two String object contains same characters in same order they are considered equals, which is what you need in many programming task. Similarly, all domain object has equality defined, but true need of equals and hashcode arise, when you use them as key in hash based collection e.g. Hashtable or HashMap. These collection classes relies on rules of  Java programming around equals and hashcode to work according to their specification, popularly known as equals-hashcode contract. According to which, you must override hashcode, if you are overriding equals and vice-versa. Problem is that this is not enforced by compiler, and if you make such mistake, your program will not work properly.



For example, any object which doesn't follows equals and hashcode contract, if used as key in HashMap, you may not be able to retrieve object again, see how HashMap works internally in Java for more details. In short, you need to override equals and hashcode, if you are writing a domain object, or you want to store them in hash based collection. Once you understand why you should override equals and hashcode, and when you should do that, it's easy to actually do that. See my post 5 tips to override equals and hashcode in Java for more details.










Why you need to override toString method


You should override toString() method for all domain object, because whenever you print them using logger or System.out.println() statements, there toString() method is called. Since default implementation of toString() is not very helpful, and only print classname@hashcode e.g. com.test.User@1033203. If you print some useful information, e.g. Arun, 1022320,  it will only help you during debugging and troubleshooting. Now there are multiple ways to override toString() in Java, see that link for some easy and productive way. For  example, if you print array in Java you will not see any meaningful value, because it doesn't override toString() method, but you can still print arrays by using Arrays.toString() method. This will now show you elements stored in array, instead of just type of array and it's hashcode.


Overriding equals, hashcode and toString in Java





I hope this help you to understand significance of equals, hashcode and toString method in Java. In fact all methods of java.lang.Object are worth reading. These are fundamental concept and solid knowledge of this will only going to help you, both during Interview and on Job. Time spent on understanding java.lang, java.util and java.io are best investment in learning Java. Always remember to override hashcode() if you are overriding equals() method and vice-versa. Failing to do so is not a compile time error but can create really subtle bugs which can take hours to debug and solve, for example your HashMap reduced to linked list due to frequent collision, you not able to retrieve object put on HashMap etc.

























Source:http://javarevisited.blogspot.com/2015/01/why-override-equals-hashcode-or-tostring-java.html

1 komentar:

  1. Thanks for this wonderful article.
    https://www.flowerbrackets.com/difference-between-equal-operator-vs-equals-method-java/

    BalasHapus