The hashCode()
and equals()
methods have been defined in Object
class which is parent class for java objects. For this reason, all java objects inherit a default implementation of these methods.Usage of hashCode() and equals()
hashCode()
method is used to get a unique integer for given object. This integer is used for determining the bucket location, when this object needs to be stored in some HashTable like data structure. By default, Object’s hashCode()
method returns and integer representation of memory address where object is stored.equals()
method, as name suggest, is used to simply verify the equality of two objects. Default implementation simply check the object references of two objects to verify their equality.Overriding the default behavior
Everything works fine until you do not override any of these methods in your classes. But, sometimes application needs to change the default behavior of some objects.
Lets take an example where your application has
Employee
object. Lets create a minimal possible structure of Employee class::public class Employee { private Integer id; private String firstname; private String lastName; private String department; public Integer getId() { return id; } public void setId(Integer id) { this .id = id; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this .firstname = firstname; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this .lastName = lastName; } public String getDepartment() { return department; } public void setDepartment(String department) { this .department = department; } } |
Above
Employee
class has some very basic attributes and there accessor methods. Now consider a simple situation where you need to compare two employee objects.public class EqualsTest { public static void main(String[] args) { Employee e1 = new Employee(); Employee e2 = new Employee(); e1.setId( 100 ); e2.setId( 100 ); //Prints false in console System.out.println(e1.equals(e2)); } } |
No prize for guessing. Above method will print “false“. But, is it really correct after knowing that both objects represent same employee. In a real time application, this must return true.
After override equals() method in Employee class :
public class Employee {
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
@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 (department == null) {
if (other.department != null)
return false;
} else if (!department.equals(other.department))
return false;
if (firstname == null) {
if (other.firstname != null)
return false;
} else if (!firstname.equals(other.firstname))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
return true;
}
}
import java.util.HashSet;
import java.util.Set;
public class HashCodeAndEqualMethod {
private final String importantField;
private final String anotherField;
public HashCodeAndEqualMethod(final String equalField, final String anotherField) {
this.importantField = equalField;
this.anotherField = anotherField;
}
public String getEqualField() {
return importantField;
}
public String getAnotherField() {
return anotherField;
}
public static void main(String[] args) {
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.setId(100);
e2.setId(100);
// Prints false in console if you are not override equals method in Employee class.
System.out.println(e1.equals(e2));
Set<Employee> employees = new HashSet<Employee>();
employees.add(e1);
employees.add(e2);
// Prints two objects if you are not override equals and hashCode() method in Employee class.
System.out.println(employees);
}
}
Output:
true
[Employee@10469e8, Employee@969cccc]
After override both
hashCode()
and equals()
method in Employee class :public class Employee {
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((department == null) ? 0 : department.hashCode());
result = prime * result + ((firstname == null) ? 0 : firstname.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.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 (department == null) {
if (other.department != null)
return false;
} else if (!department.equals(other.department))
return false;
if (firstname == null) {
if (other.firstname != null)
return false;
} else if (!firstname.equals(other.firstname))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
return true;
}
}
Output:
true
[Employee@e239d]
No comments:
Post a Comment