java - what happens if hashCode is not overriden? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
what is an objects hashcode
Let's say that I create an object, called Employee which has id, firstName, lastName and email for instance variables and corresponding setter/getter methods. How is hashCode() calculated if I don't override hashCode() in Employee object when it is stored in collection objects?

If you don't override hashcode() then the default implementation in Object class will be used by collections. This implementation gives different values for different objects, even if they are equal according to the equals() method.
Some collections, like HashSet, HashMap or HashTable use the hash code to store its data and to retrieve it. If you don't implement hashcode() and equals() in a consistent manner, then they will not function properly.
Edit:
As per Javadoc: Object.hashcode() is ''typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java(TM) programming language''. Therefore I would advise not to rely on a specific implementation. For what the implementations really do, see this answer to a similar question.

From the documentation:
As much as is reasonably practical, the hashCode method defined by
class Object does return distinct integers for distinct objects. (This
is typically implemented by converting the internal address of the
object into an integer, but this implementation technique is not
required by the JavaTM programming language.)
So basically when you store in a Map/Set/somethingThatRequiresHashCode, the JVM will use the internal memory address of that instance to calculate the hashCode, guaranteeing (as much as hash functions guarantee anything - they don't) that each distinct instance will have a unique hashCode.
This is particularly important because of the Object contract regarding equals and hashCode, since:
The equals method for class Object implements the most discriminating
possible equivalence relation on objects; that is, for any non-null
reference values x and y, this method returns true if and only if x
and y refer to the same object (x == y has the value true).
If you don't override equals, it will compare the internal address of the two references, which matches the logic behind hashCode.
If your question is more related to: Will the JVM look at the values inside an instance to determine equality/calculate hashcode, the answer is simply no, if you do:
MyObject a = new MyObject("a", 123,"something");
MyObject b = new MyObject("a", 123,"something");
a and b will have different hashcodes.

From effective Java 2nd Edition
Item 9: Always override hashCode when you override equals
A common
source of bugs is the failure to override the hashCode method. You
must override hashCode in every class that overrides equals. Failure
to do so will result in a violation of the general contract for
Object.hashCode, which will prevent your class from functioning
properly in conjunction with all hash-based collections, including
HashMap, HashSet, and Hashtable.
I suggest you read that chapter. There are a lot of examples, that you can learn, what will happen if you don't do so.

It depends on the collection, most collections should work even if the hashCode of the elements has not been overridden, except collections like HashSet which rely on the element hashCode in order to work properly.
Beware that the hashCode of a collection usually relies on the hashCode of the elements:
Returns the hash code value for this collection. While the Collection
interface adds no stipulations to the general contract for the
Object.hashCode method, programmers should take note that any class
that overrides the Object.equals method must also override the
Object.hashCode method in order to satisfy the general contract for
the Object.hashCode method. In particular, c1.equals(c2) implies that
c1.hashCode()==c2.hashCode()
See: http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html#hashCode%28%29

**type of field** **hash code formula**
boolean fieldHash = f ? 0 : 1
any integer type except long fieldHash = (int) f
long fieldHash = (int) (f ^ (f >>> 32))
float fieldHash = Float.floatToIntBits( f )
double int v=Double.doubleToLongBits(f)
fieldHash (int) (v ^ (v >>> 32))
any Object reference fieldHash = f.hashCode()
If you write a custom type you are responsible for creating a good hashCode implementation that will best represent the state of the current instance.
http://content.hccfl.edu/pollock/AJava/HashCode.htm

Related

Hashcode and equals methods contract [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 know that when we override equals() method then we need to override hashcode() as well and other way around.
But i don't understand why we MUST do that?
In Joshua Bloch Book it is clearly written that we must do that, because when we deal with hash based collections, it is crucial to satisfy the Hashcode contract and I admit that, but what if I am not dealing with hash-based collections?
Why is it still required ?
Why to Override Equals ?
A programmer who compares references to value objects using the equals
method expects to find out whether they are logically equivalent, not
whether they refer to the same object .
Now coming to HashCode
Hash function which is called to produce the hashCode should return the same hash code each and every time,
when function is applied on same or equal objects. In other words, two
equal objects must produce same hash code consistently.
Implementation of HashCode provided by Object Class is not based upon logical equivalency ,
So Now if you will not override hashCode but override equals, then according to you 2 Objects are equals as they will pass the equals() test but according to Java they are not .
Consequences :
Set start allowing duplicates !!!
Map#get(key) will not return the correct value !!
and so on many other consquences..................
Data structures, such as HashMap, depend on the contract.
A HashMap achieves magical performance properties by using the hashcode to bucketize entries. Every item that is put in the map that has the same hashcode() value gets placed in the same bucket. These "collisions" are resolved by comparing within the same bucket using equals(). In other words, the hashcode is used to determine the subset of the items in the map that might be equal and in this way quickly eliminate the vast majority of the items from further consideration.
This only works if objects that are equal are placed in the same bucket, which can only be ensured if they have the same hashcode.
NOTE: In practice, the number of collisions is much higher than may be implied above, because the number of buckets used is necessarily much smaller than the number of possible hashcode values.
As per Joshua Bloch book;
A common source of bugs is the failure to override the hashCode
method. You must override hashCode in every class that overrides
equals. Failure to do so will result in a violation of the general
contract for Object.hashCode, which will prevent your class from
functioning properly in conjunction with all hash-based collections,
including HashMap, HashSet, and Hashtable.
Failing to override hashcode while overriding equals is violation the contract of Object.hashCode. But this won't have impact if you are using your objects only on non hash based collection.
However, how do you prevent; the other developers doing so. Also if an object is eligible for element of collection, better provide support for all the collections, don't have half baked objects in your project. This will fail anytime in the future, and you will be caught for not following the contacts while implementing :)
Because that is the way it is meant to be:
Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
What issues should be considered when overriding equals and hashCode in Java?
There are use-cases where you don't need hashcode(), mostly self-written scenarious, but you can never be sure, because implementations can and might be also relying on hashcode() if they are using equals()
This question is answered many times in SO, but still I will attempt to answer this .
In order to understand this concept completely, we need to understand the purpose of hashcode and equals, how they are implemented, and what exactly is this contract(that hashcode also should be overridden when equals is overridden)
equals method is used to determine the equality of the object. For primitive types, its very easy to determine the equality. We can very easily say that int 1 is always equal to 1. But this equal method talks about the equality of objects. The object equality depends on the instance variables or any other parameter (depend purely on the implementation - how you want to compare).
This equal method needs to be overridden if we want some customized comparison, lets say we want to say that two books are same if they have same title and same author, or I can say two books are equal if they have same ISBN.
hashcode method returns a hash code value of an object. The default implementation of the Object hashcode returns a distinct integers for distinct objects. This integer is calculated based on the memory address of the object.
So we can say that the default implementation of the equals method just comapres the hashcodes to check the equality of the object. But for the book example - we need it differently.
Also Equal objects must produce the same hash code as long as they are equal, however unequal objects need not produce distinct hash codes.
In case of not using a hash based collection, you can break the contract and need not to override the hashcode method - because you ll not be using the default implementations anywhere but still I would not suggest that and would say to have it as you may need it in future when you put those things in collection

Relationship between hashCode and equals method in Java [duplicate]

This question already has answers here:
What issues should be considered when overriding equals and hashCode in Java?
(11 answers)
Why do I need to override the equals and hashCode methods in Java?
(31 answers)
Closed 9 years ago.
I read in many places saying while override equals method in Java, should override hashCode method too, otherwise it is "violating the contract".
But so far I haven't faced any problem if I override only equals method, but not hashCode method.
What is the contract? And why am I not facing any problem when I am violating the contract? In which case will I face a problem if I haven't overridden the hashCode method?
The problem you will have is with collections where unicity of elements is calculated according to both .equals() and .hashCode(), for instance keys in a HashMap.
As its name implies, it relies on hash tables, and hash buckets are a function of the object's .hashCode().
If you have two objects which are .equals(), but have different hash codes, you lose!
The part of the contract here which is important is: objects which are .equals() MUST have the same .hashCode().
This is all documented in the javadoc for Object. And Joshua Bloch says you must do it in Effective Java. Enough said.
According to the doc, the default implementation of hashCode will return some integer that differ for every object
As much as is reasonably practical, the hashCode method defined by class Object does
return distinct integers for distinct objects. (This is typically implemented by
converting the internal address of the object into an integer, but this implementation
technique is not required by the JavaTM programming language.)
However some time you want the hash code to be the same for different object that have the same meaning. For example
Student s1 = new Student("John", 18);
Student s2 = new Student("John", 18);
s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode
This kind of problem will be occur if you use a hash data structure in the collection framework such as HashTable, HashSet. Especially with collection such as HashSet you will end up having duplicate element and violate the Set contract.
Yes, it should be overridden. If you think you need to override equals(), then you need to override hashCode() 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.
The contract is that if obj1.equals(obj2) then obj1.hashCode() == obj2.hashCode() , it is mainly for performance reasons, as maps are mainly using hashCode method to compare entries keys.
Have a look at Hashtables, Hashmaps, HashSets and so forth. They all store the hashed key as their keys. When invoking get(Object key) the hash of the parameter is generated and lookup in the given hashes.
When not overwriting hashCode() and the instance of the key has been changed (for example a simple string that doesn't matter at all), the hashCode() could result in 2 different hashcodes for the same object, resulting in not finding your given key in map.get().
See JavaDoc of java.lang.Object
In hashCode() it says:
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.
(Emphasis by me).
If you only override equals() and not hashCode() your class violates this contract.
This is also said in the JavaDoc of the equals() method:
Note that it is generally necessary to override the hashCode method
whenever this method is overridden, so as to maintain the general
contract for the hashCode method, which states that equal objects must
have equal hash codes.
A contract is: If two objects are equal then they should have the same hashcode and if two objects are not equal then they may or may not have same hash code.
Try using your object as key in HashMap (edited after comment from joachim-sauer), and you will start facing trouble. A contract is a guideline, not something forced upon you.

How to avoid inserting duplicate objects in List?

I have two employee objects
Employee e1 = new Employee("1");
Employee e2 = new Employee("1");
So how to avoid inserting this second object in following List
List<Employee> list = new ArrayList<Employee>();
Can we use hashcode() and equals() methods to avoid inserting duplicate objects in the list? How?
Lists have a method to check if an object is in it or not. It internally uses the equals() method.
if(!list.contains(e2))
{
list.add(e2);
}
You can use Set to avoid inserting duplicates . But for that you need to override the hashCode() and equals() method of your Employee class to define what exactly is e1.equals(e2).
In your question, e1 and e2 are not really equal in terms of their hashcode. So you cant really equate it using .equals() or == or .hashCode().equals(). You will have to implement your own method to check for equality based on the data contained in these objects. To Java, every object instantiated using new will be a different object.
Below is excerpt from the Java Api doc for the hashcode method
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.
As much as is reasonably practical, the hashCode method defined by
class Object does return distinct integers for distinct objects. (This
is typically implemented by converting the internal address of the
object into an integer, but this implementation technique is not
required by the JavaTM programming language.)

Does hashcode number represent the memory address? [duplicate]

This question already has answers here:
How is hashCode() calculated in Java
(11 answers)
Closed 9 years ago.
I have learned that hashcode is a Unique Identification reference number, which is a hexadecimal number.
My doubt is, does the reference number represents the memory address of the object?
For example:
Employeee e1=new Employee();
System.out.println(e1.hashcode());
Will this code return me the memory address of my object?
Hashcode is not a unique identification. It's just a number that helps you distinguish objects. Two different objects may have the same hash code and it is fine.
HashCode characteristics:
If obj1 and obj2 are equal, they must have the same hash code.
If obj1 and obj2 have the same hash code, they do not have to be equal.
If Employee class hasn't overridden the hashCode() method , then it will use the one defined in its super class, probably Object class . hashCode() in Object class says ,
As much as is reasonably practical, the hashCode method defined by class Object
does return distinct integers for distinct objects. (This is typically
implemented by converting the internal address of the object into an integer,
but this implementation technique is not required by the JavaTM
programming language.)
So, in short it may or may not depending upon the implementation.Suppose, if Employee class has overridden the hashCode() as(though bad practice and useless) :
public int hashCode() {
return 10;
}
Then, you can see that it doesn't return a memory address here.
Not necessarily the memory address. It should be kept different for different objects. But it might be anything. You can also override default hashCode definition with your own.
Hashcode is a number used by JVM for hashing in order to store and retrieve the objects. For example, when we add an object in hashmap, JVM looks for the hashcode implentation to decide where to put the object in memory. When we retrieve an object again hashcode is used to get the location of the object. Note that hashcode is not the actual memory address but its a link for JVM to fetch the object from a specified location with a complexity of O(1).
Simple Answer NO
A hashcode is an integer value that represents the state of the object upon which it was called. That is why an Integer that is set to 1 will return a hashcode of "1" because an Integer's hashcode and its value are the same thing. A character's hashcode is equal to it's ASCII character code. If you write a custom type you are responsible for creating a good hashCode implementation that will best represent the state of the current instance.
So for your class you can implement the hashcode Method and return whatever you want.
hashCode is the native implementation which provides the memory address to a certain extent.
Any ways you can ovveride it.
If you look close at API
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.
I do not know how much you understand from others answers but my doubts were clear after
I read
The 3 things you should know about hashCode() by #Ralf Sternberg
According to Java documentation:
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects. (This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java programming language.)
The hashcode for objects is implementation-specific, but I would highly doubt any JVM implementation would use the memory address. Since garbage collection is a central feature of Java, that means the object could be moved and thereby have different memory addresses during its lifetime, even if its contents remain unchanged (and this would violate the hashcode spec).
Hashcode is the 32 bit signed integer that is uniquely assigned to that object. It is the result of the hash function when inserting into the hashmap

equals and hashCode

I am running into a question about equals and hashCode contracts:
here it is
Given:
class SortOf {
String name;
int bal;
String code;
short rate;
public int hashCode() {
return (code.length() * bal);
}
public boolean equals(Object o) {
// insert code here
}
}
Which of the following will fulfill the equals() and hashCode() contracts for this
class? (Choose all that apply.)
Correct Answer
C:
return ((SortOf)o).code.length() * ((SortOf)o).bal == this.code.length() *
this.bal;
D:
return ((SortOf)o).code.length() * ((SortOf)o).bal * ((SortOf)o).rate ==
this.code.length() * this.bal * this.rate;
I have a question about the last choice D, say if the two objects
A: code.length=10, bal=10, rate = 100
B: code.length=10, bal=100, rate = 10
Then using the equals() method in D, we get A.equals(B) evaluating to true right? But then they get a different hashCode because they have different balances? Is it that I misunderstood the concept somewhere? Can someone clarify this for me?
You're right - D would be inappropriate because of this.
More generally, hashCode and equals should basically take the same fields into account, in the same way. This is a very strange equals implementation to start with, of course - you should normally be checking for equality between each of the fields involved. In a few cases fields may be inter-related in a way which would allow for multiplication etc, but I wouldn't expect that to involve a string length...
One important point which often confuses people is that it is valid for unequal objects to have the same hash code; it's the case you highlighted (equal objects having different hash codes) which is unacceptable.
You have to check at least all the fields used by .hashCode() so objects which are equal do have the same hash. But you can check more fields in equals, its totally fine to have different objects with the same hash. It seems your doing SCJP 1.6? This topic is well covered in the SCJP 1.6 book from Katherine Sierra and Bert Bates.
Note: thats why its legit to implement a useful .equals() while returning a constant value from .hashCode()
It's all about fulfilling the contract (as far as this question is concerned). Different implementation (of hasCode and equal) has different limitations and its own advantages - so its for developer to check that.
but then they get different hashCode because they have a different balance?
Exactly! But that's why you should choose option C. The question wants to test your grasp on fulfilling the contract concept and not which hascode will be better for the scenario.
More clarification:
The thing you need to check always is :
Your hashCode() implementation should use the same instance variables as used in equals() method.
Here these instance variables are : code.length() and bal used in hashCode() and hence you are limited to use these same variables in equals() as well. (Unless you can edit the hashCode() implementation and add rate to it)
hashCode() method is used to get a unique integer for given object. This integer is used to determined the bucket location, when this object need to be stored in some HashTable like HashMap data structure. But default, Object's hashCode() method returns an integer to represent memory address where object is stored.
equals() method, as name suggest, is used to simply verify the equality of two objects. Default implementation just simply check the object references of two object to verify their equality.
equal objects must have equal hash codes.
equals() must define an equality relation. if the objects are not modified, then it must keep returning the same value. o.equals(null) must always return false.
hashCode() must also be consistent, if the object is not modified in terms of equals(), it must keep returning the same value.
The relation between the two method is:
whenever a.equals(b) then a.hashCode() must be same as b.hashCode().
refer to: https://howtodoinjava.com/interview-questions/core-java-interview-questions-series-part-1/
In general, you should always override one if you override the other in a class. If you don't, you might find yourself getting into trouble when that class is used in hashmaps/hashtables, etc.

Categories