Prerequisite: Equal and Hashcode Methods in Java , Why to override equal and hashcode methods
hashCode and equals method are frequently asked in Java interviews. In general, we do not override both methods but there are some scenarios/requirements when we have to override these two methods. One such scenario when we store user-defined objects in Collection classes that make use of hashing algorithm. i.e. HashTable, HashSet and HashMap.
Interview Question: Create a Map which contains address of each employee and uses employee object as a key. Store address of some employees in this map. Now create a method that accepts Map and Employee object as parameters and returns address of this employee.
Approach 1 (Without overriding hashCode and equals methods)
// Java program to create a map of employee // and address Without overriding // hashCode and equals methods import java.util.HashMap; import java.util.Map; class Employee { private int empId; private String name; public Employee( int empId, String name) { this .empId = empId; this .name = name; } } class Address { private int houseNo; private String streetName; private String city; private int pinCode; public Address( int houseNo, String streetName, String city, int pinCode) { this .houseNo = houseNo; this .streetName = streetName; this .city = city; this .pinCode = pinCode; } public String getAddress() { return houseNo + ", " + streetName + ", " + city + ", " + pinCode; } } public class Test { public static String getAddress(Map map, Employee emp) { Address adrs = (Address)map.get(emp); return adrs.getAddress(); } public static void main(String[] args) { Employee emp1 = new Employee( 110 , "Sajid Ali Khan" ); Address adrs1 = new Address( 304 , "Marol Mahrisi" , "Mumbai" , 400069 ); Employee emp2 = new Employee( 111 , "Jaspreet Singh" ); Address adrs2 = new Address( 203 , "Seepz" , "Mumbai" , 400093 ); Map<Employee, Address> map = new HashMap<>(); map.put(emp1, adrs1); map.put(emp2, adrs2); System.out.println(Test.getAddress(map, new Employee( 110 , "Sajid Ali Khan" ))); } } |
Output:
Exception in thread "main" java.lang.NullPointerException at Test.getAddress(Test.java:44) at Test.main(Test.java:59)
We expected the output as address of employee, but we get NullPointerException and that is pretty straight forward. new Employee(110, “Sajid Ali Khan”) in Map and new Employee(110, “Sajid Ali Khan”) in argument are two different instances. Hence we get NullPointerException because when we do map.get(emp), it returns null.
Approach 2 (Overriding hashCode and equals method)
// Java program to create a map of employee // and address using overriding // hashCode and equals methods import java.util.HashMap; import java.util.Map; class Employee { private int empId; private String name; public Employee( int empId, String name) { this .empId = empId; this .name = name; } @Override public int hashCode() { final int prime = 31 ; int result = 1 ; result = prime * result + empId; result = prime * result + ((name == null ) ? 0 : name.hashCode()); return result; } @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 (empId != other.empId) return false ; if (name == null ) { if (other.name != null ) return false ; } else if (!name.equals(other.name)) return false ; return true ; } } class Address { private int houseNo; private String streetName; private String city; private int pinCode; public Address( int houseNo, String streetName, String city, int pinCode) { this .houseNo = houseNo; this .streetName = streetName; this .city = city; this .pinCode = pinCode; } public String getAddress() { return houseNo + ", " + streetName + ", " + city + ", " + pinCode; } } public class Test { public static String getAddress(Map map, Employee emp) { Address adrs = (Address)map.get(emp); return adrs.getAddress(); } public static void main(String[] args) { Employee emp1 = new Employee( 110 , "Sajid Ali Khan" ); Address adrs1 = new Address( 304 , "Marol Mahrisi" , "Mumbai" , 400069 ); Employee emp2 = new Employee( 111 , "Jaspreet Singh" ); Address adrs2 = new Address( 203 , "Seepz" , "Mumbai" , 400093 ); Map<Employee, Address> map = new HashMap<>(); map.put(emp1, adrs1); map.put(emp2, adrs2); System.out.println(Test.getAddress(map, new Employee( 110 , "Sajid Ali Khan" ))); } } |
Output:
304, Marol Mahrisi, Mumbai, 400069
We get the expected output and that is because we have override hashCode and equals method properly in our code. When we do map.get(emp), it internally calls our overriding hashCode method which results in same hashcode as of employee object used as key in Map.
Once right bucket is find, equals method will be called and matches all values of both Employee object. As a result, we get correct address of Employee object.
This article is contributed by Sajid Ali Khan. If you like Lazyroar and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the Lazyroar main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.