0

I would like to understand the below scenario of equals() and hashcode() and here hashcode always returns 1.

  • Case-1: if I don't override equals and hashcode then I get size=4
  • Case-2: If I don't override equals, only override hashcode always returning 1, then size=4
  • Case-3: If I don't override hashcode, only override equals then size=4
  • Case-4: If I override equals and hashcode both , hashcode always returns 1, then size=3
  • Case-5: If I override equals and hashcode both, hashcode will be system generated, then size=3

Can 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); } } 
3
  • 3
    What were you expecting hashcode to return when its impl is return 1;? hashcode and equals are unrelated, except that if equals is true, hashcode should also be equal. Commented Mar 18, 2021 at 4:34
  • 1
    Please read on the internal workings of HashMap and you will get your answer. I do not wish to retype what has already been explained very at the given link. geeksforgeeks.org/internal-working-of-hashmap-java Commented Mar 18, 2021 at 4:35
  • 2
    I think I'd like you to try to explain these yourself, then ask for corrections as needed. (I've done that for other questions.) The fact is the reasons are fairly obvious and you should try to figure them out. Commented Mar 18, 2021 at 4:37

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.