简体   繁体   中英

Java - Equals and Hashcode comparision

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);
        }
    }

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM