How the hash Code method is calculating the value? [duplicate] - java

This question already has answers here:
How is hashCode() calculated in Java
(11 answers)
Closed 3 years ago.
The hashCode() method return a serie of numbers, but two different objects can have the same result.
So how this function is really calculating that value,internally ?
Is that related to memory case, and what's the element included in th calculation?

According to the Object javadoc, hashCode method may returns the object's address in memory at some point in time
The hashCode may or may not be implemented as some function of an
object's memory address at some point in time
https://docs.oracle.com/javase/10/docs/api/java/lang/Object.html#hashCode()
Remember that this method is useful to compare whether two or more or object are the same together with equals method,but you can override this method to return the same hashcode if some attributes (e.g PKs) are the same although them are different objects in memory

Related

Why we should Override hashcode() when overriding equals() method? [duplicate]

This question already has answers here:
Why do I need to override the equals and hashCode methods in Java?
(31 answers)
Closed 9 years ago.
Why we should always override hashCode() method whenever we override equals() method? As per my understanding they both seem to fulfill different purpose. hashCode() method is used in hashtables to determine the equality of keys. However equals() method is used to determine the equality of two objects.
If two objects are equal according to the equals method, their hashcodes must be equal as well. Otherwise, lookup in the hash table would fail.

Why it is necessary to override hashcode and equals method of key for Hashmap? [duplicate]

This question already has answers here:
What issues should be considered when overriding equals and hashCode in Java?
(11 answers)
Closed 9 years ago.
I created a HashMap having Student as key and String as value.
Now everywhere i have read It is necessary to override equals and hashcode method if using as a key for hashmap.
But I did not override it. And insert multiple key value pairs in hashmap.
I am also able to fetch it back.
So why it is necessary?
They are required when you want to use your objects as useful hashing keys into collections that use hashing.
Have your tried to add the Student objects which are meaningfully equal?
First understand the significance of equals method in java
Read the significance of equals and hashcode

Should the 'equals' (Object) method be overridden when overriding hashCode() in Java? [duplicate]

This question already has answers here:
What issues should be considered when overriding equals and hashCode in Java?
(11 answers)
Closed 9 years ago.
Should the equals (Object) method be overridden when overriding hashCode() in Java?
I have read the contract that overriding equals, you should override hashCode. Is the vice versa true?
I was thinking of a scenario where I don't compare objects, no equals method.
Yes, it should be overridden. If you think you need to override hashCode(), then you need to override equals() and vice versa. The general contract of hashCode() is:
Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
Joshua Bloch makes it clear in chapter 3 of his "Effective Java" - these must be in lockstep. They should always be overridden together.

The behaviour of equals() method in Java [duplicate]

This question already has answers here:
Weird Integer boxing in Java
(12 answers)
What is the difference between == and equals() in Java?
(26 answers)
Closed 9 years ago.
Consider the following Java code:
Object a = new Integer(2);
Object b = new Integer(2);
System.out.println(a.equals(b));
Object x = new Object();
Object y = new Object();
System.out.println(x.equals(y));
The first print statement prints true and the second false.
If this is an intentional behavior, how this helps programming in Java?
If this is not an intentional behavior, is this a defect in Java?
I'm going to answer your question with reservations, but you should know that you are hurting yourself if the intent of the question was to get you to learn and your solution was to ask StackOverflow. That aside...
This behavior is intentional.
The default equals() method on java.lang.Object compares memory addresses, which means that all objects are different from each other (only two references to the same object will return true).
java.lang.Integer overrides this to compare the value of the Integers, so two different Integers both representing the number two compare equal. If you used == instead, you would get false for both cases.
Standard practice in Java is to override the equals method to return true for objects which have the same logical value, even if they were created at different times (or even with different parameters). It's not very useful to have objects representing numbers if you don't have a way to ask, "do these two things represent the same value?".
Incidentally, and this is a tangent here, Java actually keeps a cache of Integer objects for small values. So sometimes you may get two Integer objects where even the == operator will return true, despite you getting them from two different sources. You can even get code that behaves differently for larger integers than it does for smaller, without having it look at the integral values!
This is intended behaviour.
Object.equals() considers the object identity (i.e. an object is only equal to itself), which is the only thing you can do for generic objects.
Integer overrides the method to depend on the integer value, since two Integer objects with the same value are logically equal. Many other classes also override equals() since it's a core mechanism of the standard API and a lot of functionaliy e.g. in the collections framework depends on it.
Why do are you puzzled by the behaviour anyway? Most people are only confused by the == operator not behaving like that (it works like Object.equals()).
The equals method in Java serves a specific purpose: it determines if the objects are logically equal, i.e. their content is the same, whatever that may mean in the context of each specific class. This is in contrast to the objects being the same: two different objects could be logically equivalent.
Going back to your example, a and b are different objects that represent the same logical entity - an integer value of 2. They model the same concept - an integer number, and integer numbers with the same value are identical to each other. a and b are, therefore, equal.
The x and y objects, on the other hand, do not represent the same logical entity (in fact, they do not represent anything). That's why they are neither the same nor are equivalent.
It is intentional, of course.
When comparing Integer objects, equals returns true if their values (in your case, 1) are equal.
Applied on different objects of type Object, it returns false.
x.equals(x)
would return true.
See also Object.equals() doc. By the way, consider using Integer.valueOf(2) rather than new Integer(2) as it reduces memory footprint.
One last funny thing Integer.valueOf(2)==Integer.valueOf(2) will return true but Integer.valueOf(2000)==Integer.valueOf(2000) will return false because in the first case you will receive twice the same instance of the Integer object (there is a cache behind) but not in the second case because the cache is only for values between -127 to 128

Hashmap gives Null when trying to get an objects that exists in it [duplicate]

This question already has answers here:
Why do I need to override the equals and hashCode methods in Java?
(31 answers)
Closed 7 years ago.
I am running into this weird issue where I am iterating over a list of responses. when I try to get the answer from each response by the question, most of them get the answer correctly except one where getting the answer from the hashmap gives null. I have ran the debug mode in eclipse, and compared the question that I try to get its value from the hashmap getAnswerMap() with the one inside that hashmap and both seem to be exactly the same, but I still get null.
for (SurveyResponse response : responses) {
MultipleChoiceAnswer answer = (MultipleChoiceAnswer) response.getAnswerMap().get(question);
....
....
}
Then, I thought it is a hashcode issue, so I added another ugly line of code to check hashcodes, and they actually have the same hashcode and the additional following line worked and did set answer correctly.
for (SurveyResponse response : responses) {
MultipleChoiceAnswer answer = (MultipleChoiceAnswer) response.getAnswerMap().get(question);
for (Entry entry: response.getAnswerMap().entrySet()) {
if (entry.getKey().hashCode() == question.hashCode()) answer = (MultipleChoiceAnswer) entry.getValue();
....
....
}
However, this is very ugly and I would really like to get the answer correctly from the hashmap. Any suggestions?
UPDATE:
calling both hashCode() and equals() method on both objects shows that both have equal hashcodes and equals() returns true. I suspect that as one of the answers down indicate, the problem might be that the question was inserted with a different hashcode when it was inserted in the hashmap. Therefore, calling the get method in question returns null because the object I am trying to get does not have the same hashcode as the old one. Extremely helpful answers guys!
One thing to watch out for: Make sure the class you're using as a key is immutable -- otherwise, a key will hash to one thing when you put it in, but something different when you take it out.
Edit: It doesn't have to be immutable, but it has to be true that it can only be changed in a way that doesn't change the hashcode. Making the entire object immutable is the simplest way to do that, but it's not the only way.
One more glass ball guess:
You have an equals method like this one:
class Question {
// ...
public boolean equals(Question q) {
// do intelligent comparison
}
public int hashCode() {
// calculate hash code
}
}
But here you don't really override the equals(Object) method from Object, but simply declare a new one beside this. The HashMap does not know anything about your new method, it will simply call the original one for comparing your key object in the map with the query key (after finding one with matching hashCode).
Declare the method like this, instead:
#Override
public boolean equals(Object o) {
if(! (o instanceof Question))
return false;
Question q = (Question)o;
// do intelligent comparison
}
(The #Override annotation lets the compiler check that you are really overriding a method here, not just creating a new one.)
To make an object an 100% deterministic key with a HashMap you need to override hashCode() and equals() where they are consistent in that equals() always returns true when the hashCode()s are the same.
Here is an old article from Brian Goetz on IBM developerWorks, but the contents are still applicable today:
Why override equals() and hashCode()?
What would happen if Integer did not
override equals() and hashCode()?
Nothing, if we never used an Integer
as a key in a HashMap or other
hash-based collection. However, if we
were to use such an Integer object for
a key in a HashMap, we would not be
able to reliably retrieve the
associated value, unless we used the
exact same Integer instance in the
get() call as we did in the put()
call. This would require ensuring that
we only use a single instance of the
Integer object corresponding to a
particular integer value throughout
our program. Needless to say, this
approach would be inconvenient and
error prone.
The interface contract
for Object requires that if two
objects are equal according to
equals(), then they must have the same
hashCode() value. Why does our root
object class need hashCode(), when its
discriminating ability is entirely
subsumed by that of equals()? The
hashCode() method exists purely for
efficiency. The Java platform
architects anticipated the importance
of hash-based collection classes --
such as Hashtable, HashMap, and
HashSet -- in typical Java
applications, and comparing against
many objects with equals() can be
computationally expensive. Having
every Java object support hashCode()
allows for efficient storage and
retrieval using hash-based
collections.
It's likely that you haven't overridden equals(..) correctly - it is a requirement for a HashMap to work correctly

Categories

Resources