Use an object as a key in HashMap or HashSet in Java
This post will discuss how to use an object as a key in hash-based collections like HashMap, HashSet, and Hashtable in Java.
Problem:
First, let’s take an example to demonstrate the default behavior on using an object as a key in hash-based collections like HashMap, HashSet, and Hashtable in Java.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import java.util.HashSet; import java.util.Set; class Employee { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } } class Main { public static void main(String[] args) { Employee e1 = new Employee("John", 20); Employee e2 = new Employee("John", 20); Set<Employee> employees = new HashSet<>(); employees.add(e1); employees.add(e2); System.out.println(employees); } } |
Output:
[{name='John', age=20}, {name='John', age=20}]
As evident from the generated output, the HashSet contains both e1 and e2 objects even though e1 and e2 have the same value of instance variables. This is because two objects are considered equal only if their references point to the same object, which is not the case here.
Solution:
The hash-based collections are organized like a sequence of buckets, where the hash code value of an object is used to determine the bucket where the object would be stored, and the object is linearly searched in the bucket using the equals method. Therefore, to use an object as a key in HashMap, HashSet, or Hashtable in Java, we need to override equals and hashcode methods of that object since default implementation of these methods simply check for the instance equality.
Let’s take an example to demonstrate the benefit of overriding the equals and hashCode method in Java:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
import java.util.HashSet; import java.util.Set; class Employee { private String name; private int age; public Employee(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } Employee employee = (Employee) o; if (age != employee.age) { return false; } if (!name.equals(employee.name)) { return false; } return true; } @Override public int hashCode() { int result = name.hashCode(); result = 31 * result + age; return result; } @Override public String toString() { return "{" + "name='" + name + '\'' + ", age=" + age + '}'; } } class Main { public static void main(String[] args) { Employee e1 = new Employee("John", 20); Employee e2 = new Employee("John", 20); Set<Employee> employees = new HashSet<>(); employees.add(e1); employees.add(e2); System.out.println(employees); } } |
Output:
[{name='John', age=20}]
As evident from the generated output, the set contains only one Employee object even though two different Employee objects are added. This is because we have overridden both equals() and hashCode() method in the Employee class, and e1 and e2 objects now points to the same bucket and also holds the same location within the bucket.
That’s all about using an object as a key in HashMap or HashSet in Java.
Also See:
Why do we need to override equals and hashcode methods in Java?
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)