Reputation: 11985
I would like to understand the below scenario of equals()
and hashcode()
and here hashcode always returns 1.
equals
and hashcode then I get size=4equals
, only override hashcode
always returning 1, then size=4hashcode
, only override equals
then size=4equals
and hashcode
both , hashcode
always returns 1, then size=3equals
and hashcode
both, hashcode
will be system generated, then size=3Can somebody explain how its internally and case of each scenario?
Code
import java.util.HashMap;
import java.util.Map;
public class Employee {
private String name;
private int age;
public Employee() {
}
public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Employee [name=" + name + ", age=" + age + "]";
}
@Override
public int hashCode() {
// final int prime = 31;
// int result = 1;
// result = prime * result + age;
// result = prime * result + ((name == null) ? 0 : name.hashCode());
return 1;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
class Main {
public static void main(String[] args) {
Employee prateek = new Employee("Prateek", 32);
Employee prateek1 = new Employee("Prateek", 32);
Employee savani = new Employee("Savani", 40);
Employee karan = new Employee("Karan", 18);
Map<Employee, String> map = new HashMap<>();
map.put(prateek, "Prateek");
map.put(savani, "Savani");
map.put(prateek1, "Prateek");
map.put(karan, "Karan");
System.out.println("Size = "+map.size());
System.out.println(map);
}
}
Upvotes: 0
Views: 89
Reputation: 10084
Bohemian's answer is exactly correct. For example, the following hashCode()
method fulfills the contract and programs will run correctly:
public int hashCode() {
return 42;
}
The reason that programs with this method are correct is because the contract for hashCode()
is fulfilled: equal instances will always have the same hash code.
But the reason that this hashCode()
method is a problem is because it returns the same hash for both equal and unequal instances. For best performance, developers should try to write hashCode()
methods that generate distinct int values for unequal instances. This is not required by the contract for hashCode()
but it is essential if good performance is important.
For example, with the method above, every instance that is added to a HashMap
will be distributed to the same bucket. The result is that performance degrades. The best hash function will do a good job of distributing unequal instances into separate buckets. For this reason, your case #2 could result in serious performance problems if those instances were used in a HashMap.
Upvotes: 0
Reputation: 425033
The contract between equals()
and hashCode()
is basically: if equals() is true, hashCode() should return the same value.
From the javadoc:
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.
If that isn't the case, behaviour of hash-based collections/operations is undefined.
Upvotes: 2