7

if I remember correctly the default hashCode() implementation in java of an object of type Object() is to return the memory address of the object. When we create our own classes, I read that we want to override hashCode() so that when we insert them into a hash related collection like HashMap() it will work properly. But why is a memory address bad?

Sure we will EVENTUALLY run out of memory and you'll have collisions, but the only case where I see this being a problem is where you are dealing with TONS of data and have very little memory, and then it would START to affect performance because hash related collections in java resolve collisions by chaining(a bucket will link to a list of values that resolved to the same hashcode/index).

asked Apr 12, 2013 at 18:05
5
  • 3
    You're not on the problem. You could start reading this. The problem can't be seen independantly of the equality concept. Commented Apr 12, 2013 at 18:06
  • 1
    There is nothing bad about it at all, it needs to be changed sometimes for other reasons. Commented Apr 12, 2013 at 18:16
  • The default hashCode() has nothing to do with memory addresses. The documentation mentions memory addresses as a possible input for the hash code calculation, but that’s not how it is implemented in any recent JVM. Commented Feb 14, 2018 at 12:56
  • @Holger it could have something to do with memory access, there are 5 strategies to choose from; but default is not memory based indeed, it's Marsaglia XOR Shift in 8 at least Commented Feb 14, 2018 at 13:39
  • Probably before asking this question you should understand how hash maps work Commented Mar 26, 2019 at 21:21

3 Answers 3

31

The default implementation works fine if every object is unique. But if you override equals() then you are implicitly saying that objects with different addresses can be equivalent to each other. In that case you have to also override hashCode().

Think of the String class.

String s1 = new String("foo");
String s2 = new String("foo");

These two strings are equal and so their hash codes must be equal. But they are distinct objects with different addresses.

s1 == s2 // false, different addresses
s1.equals(s2) // true, same contents

Using their addresses as hash codes would be an error. Therefore, String overrides hashCode() to ensure that equal strings have equal hash codes. This helps meet hashCode()'s contract, which is:

If a.equals(b) is true, then a.hashCode() == b.hashCode().

Bottom line: If you override equals(), also override hashCode().

answered Apr 12, 2013 at 18:08
4
  • thanks, it looks like it all depends on how you define equality then. In the example you provided equality was determined by their string values so using Object()'s hashCode() would be bad because you would have 2 different entries in your hashmap although they are the same. I looked up how Java implemented hashCode() for string and found this: java-bytes.blogspot.com/2009/10/hashcode-of-string-in-java.html; would someone care to explain this or how to override hashCode() in general? All the examples I've seen online look complicated. Commented Apr 12, 2013 at 18:21
  • Effective Java by Josh Bloch covers this well and has strategies for implementation. Ides will also generate reasonable implementations for you. For example an Employee class may be uniquely identified by its employee I'd. In which case you will use it do equality and hashing. Josh Bloch suggests using some technique to spread closely related numbers (making the hash more efficient (core java books explain why this is good). If your class is unique across multiple fields (composite key), then each of these should be used in your equality and hash methods Commented Apr 12, 2013 at 20:59
  • I believe the "foo" String example isn't precise since Java interns String literals and constants, so s1 == s2 is true even though they are different objects. Commented Apr 11, 2014 at 13:06
  • @ChaimKut neither of those objects are string literals though; it is true that "foo" == "foo" will return true on hotpost (and likely all other JVMs too), but new String("foo") creates a new object, which will have a different address. Commented Dec 22, 2015 at 14:50
1

Exact key objects used while putting objects into hashmap may not be available to access the map later on in your program. So you will end up overriding equals method. When you override equals method you make sure that their hashcodes are also equal, otherwise you cannot retrieve the objects from the hashmap.

answered Apr 1, 2014 at 13:58
0

While you don't use equals method it's OK to not define hashCode, but after that contract of hashCode is to give same result for objects, that equals. You can't be sure it will, so you need to rewrite it yourself

hashCode

answered Apr 12, 2013 at 18:07

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.