0

I have an object which has one field- double[] _myField it's hashcode is

public int hashCode() {
 final int prime = 31;
 int result = 1;
 result = prime * result + Arrays.hashCode(_myField);
 return result;
}

However if I used the object as a key in a Map I get the following weird behavior:

for (Map.Entry<MyObject, String> entry: _myMap.entrySet())
 {
 if (entry.getValue() != _myMap.get(entry.getKey()))
 {
 System.out.println("found the problem the value is null");
 }
 }

The only reason I can think of that the above IF statement is true is that I get a different hashcode for the key.

in fact, I have changed the hashcode function to return 1 in all cases. Not efficient, but good for debugging and indeed the IF statement is always false.

What's wrong with Arrays.hashcode()?

Pls note (after reading some comments): 1) As for the usage of != in the IF statement, indeed it compares references but in the above case it should have been the same. Anyhow the weird thing is that the right hand side returns NULL 2) As for posting Equals function. Of course I've implemented it. But it is irrelevant. Tracing the code in debug reveals that only hashcode is called. The reason for that is presumably the weird thing, the returned hashcode is different from the orignal one. In such cases the Map doesn't find a matching entry and therefore there is no need to call Equals.

asked Nov 2, 2011 at 13:19
3
  • 7
    Can you also post your implementation of MyObject.equals()? Commented Nov 2, 2011 at 13:21
  • I can but it is irrelevant. since when I traced in debug mode the hashcode function was called and yielded a different hashcode than the original. Given that the Java map implementation did not get to call equals. It wasn't necessary. Commented Nov 2, 2011 at 23:30
  • 2
    Interesting! Can you post enough code for us to reproduce the problem ourselves? Commented Nov 3, 2011 at 3:01

3 Answers 3

5

Is the array being changed while it's in the map? Because that will change the outcome of the result.

answered Nov 2, 2011 at 13:22
2
  • 1
    +1. Even it it's not being changed, it's a bad idea to use something with a hash code that might change as a HashMap key or in HashSets. Commented Nov 2, 2011 at 13:41
  • as can be seen in the answer, the array did change. Commented Dec 7, 2011 at 14:22
2

Implementing hashCode is not enough. You also need to implement equals object. In fact whenever you implement hashCode for an object, you MUST implement equals as well. Those 2 work together.

You need to implement equals for your object and ensure that whenever equals is true for 2 objects, their hashCode also matches.

answered Nov 2, 2011 at 13:24
9
  • 4
    != compares the object references and does not call equals Commented Nov 2, 2011 at 13:27
  • 3
    @Gandalf: this is irrelevant for the problem, though. if equals and hashCode were implemented correctly, the value obtained from the entry should be identical to the value obtained by the get method. Commented Nov 2, 2011 at 13:36
  • @JBNizet I know, but this comment was very relevant to the answer it commented (see its edit history) ;) And I didn't want some people to start to believe that != behaves like this. Commented Nov 2, 2011 at 13:48
  • "In fact whenever you implement hashCode for an object, you MUST implement equals as well" - this is incorrect. All that matters is that two objects that are equal have the same hash code. You are free to change hashCode as long as two equals objects has the same hash code. Commented Nov 2, 2011 at 15:38
  • @SteveKuo Right, that is what matters, but if you provide your own hashCode implementation, how can you guarantee it matches what equals returns if you don't overload it, huh? Magic? Commented Nov 2, 2011 at 15:43
0

Trying to reproduce the problem on a clean slate revealed it is not reproducible.

Hence, further investigation revealed that the problem was the _myField used for Hash was changed while the object was stored in the map. As expected the map is corrupted.

Sorry for the time wasted by those who tried to answer the wrong question.

answered Nov 9, 2011 at 23:50

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.