Presentation is loading. Please wait.

Presentation is loading. Please wait.

Marcus Biel, Software Craftsman

Similar presentations


Presentation on theme: "Marcus Biel, Software Craftsman"— Presentation transcript:

1 Marcus Biel, Software Craftsman
equals and hashCode Hi, welcome to my free Java video course, episode 22. In this episode I will talk about the two methods hashCode and equals. hashCode and Equals both follow a contract, that ties them closely together, which is also why I am talking about both methods in just one episode. Marcus Biel, Software Craftsman

2 Marcus Biel, Software Craftsman
equals and hashCode Equals and hashCode both follow a contract, that ties them closely together, which is also why I am talking about both methods in just one episode. Marcus Biel, Software Craftsman

3 Marcus Biel, Software Craftsman
equals and hashCode Knowing all the details about these two methods will make you a better programmer today, so get yourself some popcorn and listen carefully. Marcus Biel, Software Craftsman

4 @Override public boolean equals(Object o)
Let’s start with the equals method. What does it do, what’s it useful for?

5 @Override public boolean equals(Object o)
The Equals method is used to compare two objects for equality, similar to the equals operator that is used for primitive values.

6 @Override public boolean equals(Object o)
But before going into much more detail, let’s first jump into my IDE and see this in action.

7 @Override public boolean equals(Object o)
Before we are able to implement the equals method, we need to come up with a proper design first.

8 @Override public boolean equals(Object o)
Actually many developers just skip the design phase and simply click on “auto generate”, which may lead to severe bugs or at least to suboptimal performance. Let me show you how you can properly do it.

9 When are two objects equal?
First of all you have to define what it is in your specific program, that makes two car instances equal, or unequal. myOldCar myPorsche mumsCar dadsCar myOldCar myPorsche mumsCar dadsCar

10 When are two objects equal?
In your program, are two cars equal when they have the same manufacturer maybe? myOldCar myPorsche mumsCar dadsCar myOldCar myPorsche mumsCar dadsCar manufacturer?

11 When are two objects equal?
When they have the same manufacturer and color? color? myOldCar myPorsche mumsCar dadsCar myOldCar myPorsche mumsCar dadsCar manufacturer?

12 When are two objects equal?
the same engine? color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer?

13 When are two objects equal?
or the same number of wheels? color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? number of wheels?

14 When are two objects equal?
The same top speed? color? top speed? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? number of wheels?

15 When are two objects equal?
The same vehicle identification number or VIN in short? color? top speed? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN? number of wheels?

16 When are two objects equal?
Based on the knowledge of the business you are working in, you have to decide which fields are identifying and which fields are redundant and not helpful for the equal comparison. Besides, for improved performance, you need to define in which order you want to compare the attributes. color? top speed? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN? number of wheels?

17 When are two objects equal?
Are there any fields that have a high chance to be unequal? Are there fields that may be compared faster then others? To implement a meaningful equals method, you must first analyze all these aspects in great detail. color? top speed? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN? number of wheels?

18 When are two objects equal?
Let’s go through this process with my example. I would assume that the car’s top speed relates to the type of the engine in some form; so that seems to be a redundant field that will not be helpful for the equals implementation, so let’s remove it. color? top speed? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN? number of wheels?

19 When are two objects equal?
Let’s say the number of wheels is always four in our specific example, so number of wheels would also not help us to differentiate a car. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN? number of wheels?

20 When are two objects equal?
What about the VIN? color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

21 When are two objects equal?
Well, this again depends on the type of program you want to create. For a public authority, like the police, this one is probably the only proper way of identification. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

22 When are two objects equal?
But what about a program used by the manufacturer itself? While the car is still being build and not sold yet, I would assume the VIN is of less importance. But I personally wouldn’t know that in detail. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

23 When are two objects equal?
This is what YOU will have to clarify with the business people of YOUR company or YOUR department. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

24 When are two objects equal?
Based on their knowledge, you have to select which attributes to compare in which order. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

25 When are two objects equal?
In my artificial example here I’m the developer as well as the business analyst. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

26 When are two objects equal?
So for my example I just arbitrarily define that two cars with different VIN numbers can be seen as equal. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer? VIN?

27 When are two objects equal?
Therefore I will not include this field in my equals comparison later on. color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer?

28 When are two objects equal?
Now before you think - “that’s it, I am sorry -there is actually some more theory to cover color? myOldCar myPorsche mumsCar dadsCar engine? myOldCar myPorsche mumsCar dadsCar manufacturer?

29 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null In the introduction I already told you that there is a contract of equals and hashCode we have to fulfil. First of all, there are five conditions our equals implementation has to comply with. Believe me, it looks much more scary then it actually is.

30 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null Let’s go through each of them slowly.

31 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null Reflexivity - An object must be equal to itself, so that when I call myOldCar.equals(myOldCar) it returns true.

32 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null I think this makes sense and should be easy to understand.

33 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null Symmetry - two objects must agree whether or not they are equal

34 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null If myOldCar.equals(someOtherCar) returns true, then someOtherCar.equals(myOldCar) must also return true.

35 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null This sounds obvious and very simple, when in fact it is not such a simple condition when it comes to inheritance. If you have a Car class and a BMW class which is extending the Car class, it could happen that your BMW is equal to a Car, but the same Car is not equal to the BMW, as every BMW is a Car, but not every Car is a BMW.

36 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null So the symmetry rule can actually lead to some nasty problems. There are quite a few interesting articles online discussing potential symmetry issues of the equals method.

37 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null Cover each contract condition with a dedicated unit test to make sure your class stays fully compliant with the contract.

38 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null Our next condition is Transitivity. If one object is equal to a second, and the second to a third, the first must be equal to the third

39 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null This rule sounds much more complicated then it actually is. If object a is equal to object b and object b is equal to object c, they should all be equal to each other, so that c is also equal to a.

40 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null Consistency - If two objects are equal, they must remain equal for all time, unless one of them is changed.

41 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null So when you repeatedly compare the same two objects with the equals method, it should always return the same result.

42 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null In other words, calling the equals method should not alter the object in any way.

43 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null The last rule “Null returns false” is what Josh Bloch calls “Nonullity”.

44 equals contract Reflexivity an object must be equal to itself Symmetry
two objects must agree whether or not they are equal Transitivity if one object is equal to a second, and the second to a third, the first must be equal to the third Consistency if two objects are equal they must remain equal for all time, unless one of them is changed Null returns false all objects must be unequal to null When null is given as a parameter to any equals method, this should always return false and never throw a NullPointerException.

45 @Override public int hashCode()
So now you know quite a bit about the equals method, but what is the hashCode method actually useful for?

46 @Override public int hashCode()
For processing, similar objects are usually put into a “collection”. Such a collection in Java is like a more powerful array, or an array on steroids as I often call it.

47 @Override public int hashCode()
Besides other things, it allows you to look up objects not only based on their index position, but also based on their specific values. This is were the equals method comes into play. To speed up this look up process, the Java creators added specific hash based containers, that will use the hash value as a grouping mechanism to reduce the number of equal comparisons needed.

48 In the optimal case, each object that is considered unequal by the equal method will also return a different hashCode. This hashCode is used to group the objects in so called “buckets”. -9897 7 44831 -129 myPorsche mumsCar dadsCar myOldCar

49 Now in this optimal case, you will be able to find each object simply by a lookup based on it’s hash value. -9897 7 44831 -129 myPorsche mumsCar dadsCar myOldCar

50 Hash collisions However, there may also be something called “Hash Collisions”, where two unequal objects will share the same hashCode, in which case they end up in the same bucket. -391 1 myOldCar dadsCar mumsCar myPorsche

51 Hash collisions Now if I am looking for dadsCar, I have to lookup the correct bucket based on the hashCode minus three hundred ninety one that dadsCar will return. However as there is a hash collision, I will on top have to do an equals comparison on a list of two cars in this case. -391 1 myOldCar dadsCar mumsCar myPorsche

52 Hash collisions A technically legal but inadmissible bad performing hashCode implementation could statically return 42 for all objects. In this case however the whole hashCode logic would not help at all - in the end you would have to do an equals comparison on the entire list of cars, just as if the hashing logic had never existed. 42 myOldCar myPorsche mumsCar dadsCar

53 Hash collisions Okay, now that I have talked about the general idea of the the hashCode method, I have to further tell you about the contract that the hashCode method has to fulfil so that both hashCode and equals methods will work as designed. 42 myOldCar myPorsche mumsCar dadsCar

54 hashCode contract For any two objects return same hashCodes when equals returns true The first condition that has to be fulfilled by the hashCode method is:   

55 hashCode contract For any two objects return same hashCodes when equals returns true For any two objects return same hashCodes when equals returns true   

56 hashCode contract For any two objects return same hashCodes when equals returns true To achieve this, use the same identifying attributes for both methods, in the same order.   

57 hashCode contract For any two objects return same hashCodes when equals returns true Don’t worry to much now if you don’t fully understand what I mean. As soon as I’m finished introducing you to the hashCode contract I will jump back in my IDE and show you a practical example.   

58 hashCode contract For any two objects return same hashCodes when equals returns true When hashCode is invoked more then once on the same object, it must consistently return the same int value as long as the object is not changed When hashCode is invoked more then once on the same object, it must consistently return the same int value as long as the object is not changed. This rule is similar to the equals consistency rule I introduced you before. Both equals and hashCode methods must return consistent results.   

59 overwrite hashCode whenever you overwrite equals
To fulfil this contract you should overwrite hashCode whenever you overwrite equals and vice versa.   

60 overwrite hashCode whenever you overwrite equals
Also, when you add or remove attributes from your class you will most probably also have to adjust your equals and hashCode methods.   

61 aim to return different hashCodes when equals returns false
Last but not least, aim to return different hashCodes when equals returns false. This is not a hard and fast rule, but it will improve the performance of your program by minimizing the number of hash collisions.   

62 aim to return different hashCodes when equals returns false
To the extreme, the hashCode contract would allow to statically return 42 for all objects. As Josh Bloch states in his book “Effective Java” however, this could result in quadratic rather then linear execution time and therefore could be the difference between working and not working.   

63 aim to return different hashCodes when equals returns false
Actually, the hash code method is a rather complicated beast. I couldn’t practically fit in all details without risking that you would fall as sleep.   

64 aim to return different hashCodes when equals returns false
Therefore I have done a follow-up tutorial that will give you an in-depth view on the hashCode method, which you will need to understand to become an expert in Java programming. Below this video there is a link you can click to watch my follow up tutorial for the hashCode method.   

65 Copyright © 2015 Marcus Biel All rights reserved


Download ppt "Marcus Biel, Software Craftsman"

Similar presentations


Ads by Google