I haven't overridden much of hashCode() and equals() methods so I may be wrong My question is for the last line where
dep1.equals(emp2)
is being compiled successfully(why) (I am expecting compilation error as they have different types) and after compiling I get following
15 15 false
where I am expecting 15 15 true since I am checking the hashcode in the equals method.
class Employee {
private String name;
private int id;
public Employee(String name, int id) {
this.name = name;
this.id = id;
}
public int hashCode() {
return this.id;
}
public boolean equals(Employee employee) {
return this.hashCode() == employee.hashCode();
}
public int getEmployeeId() {
return this.id;
}
}
class Department {
private String name;
private int id;
public Department(String name, int id) {
this.name = name;
this.id = id;
}
public int hashCode() {
return this.id;
}
public boolean equals(Department department) {
return this.hashCode() == department.hashCode();
}
public int getDepartmentId() {
return this.id;
}
}
public class JavaCollections {
public static void main(String args[]) {
Employee emp2 = new Employee("Second Employee", 15);
Department dep1 = new Department("Department One", 15);
System.out.println(dep1.hashCode()+" "+emp2.hashCode()+" " + dep1.equals(emp2));
}
}
First, for the reason why this compiles: all classes in Java inherit from
java.lang.Object
, which definesequals(Object)
method, and provides a default implementation. This is the method that you call when you compare anEmployee
and aDepartment
, not one of the overloads that you have provided.Your
equals
code compiles fine, because the compiler does not know that you thought you were overridingequals
when you actually didn't. The compiler thinks that you want to make a new methodto compare
Department
objects to otherDepartment
objects.If you are writing a code that overrides a method of a superclass, add
@Override
annotation to it, like this:Now the compiler will correctly complain to you that your method does not in fact override a method in its base class, alerting you to the problem at compile time.
To fix your code change the signatures of
equals
to takeObject
, add@Override
, check fornull
and for the correct type, do the cast, and then do the actual comparison:Note: Implementing
equals
like thisis very fragile. Although it works in your case, when hash code is a unique ID of the object, this wouldn't survive a code refactoring when
hashCode
is replaced with some other implementation, for example, an implementation that considers bothid
andname
. If you want to rely on comparing IDs, compare IDs directly, without callinghashCode
to get them.