In looking at different options for overriding hashCode(), I was directed to Objects.hashCode(Object[]) in Google’s guava-libraries (javadoc). The javadoc states that it delegates to Arrays.hashCode(Object[]). Is it safe to use this method in many different object types? Isn’t this prone to hash collision, or is this not likely simply because containers usually only contain one type of object?
As a simple example, consider the following classes,
public class Student {
private final String name;
public Student(String name) {
this.name = name;
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
}
public class Teacher {
private final String name;
public Teacher(String name) {
this.name = name;
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
}
public class HashCodeDriver {
public static void main(String[] args) {
final String name = "moe";
Student s = new Student(name);
Teacher t = new Teacher(name);
long studentHash = s.hashCode();
long teacherHash = t.hashCode();
System.out.println("studentHash=" + studentHash + " teacherHash=" + teacherHash);
if(studentHash == teacherHash) {
System.out.println("hash codes match");
}
else {
System.out.println("hash codes don't match");
}
}
}
Output:
studentHash=108322 teacherHash=108322
hash codes match
The objects are two different types but are generating the same hash code. Isn’t this a problem? Should I pass in the class as the first parameter to prevent this collision? For example,
public class Student {
private final String name;
public Student(String name) {
this.name = name;
}
@Override
public int hashCode() {
return Objects.hashCode(Student.class, name);
}
}
public class Teacher {
private final String name;
public Teacher(String name) {
this.name = name;
}
@Override
public int hashCode() {
return Objects.hashCode(Teacher.class, name);
}
}
Is this why the javadoc warns about only supplying a single object to this method? From the javadoc,
Warning: When a single object is supplied, the returned hash code does not equal the hash code of that object.
It’s not a problem when 2 different objects of 2 different types have the same hash code.
Hopefully, when you are going to build your
HashMapyou are not going to mix Students and Teachers as the keys to that map. And even in the case when you want to doHashMap<Object, Object>you will be OK, becauseThis is why it’s important to override both
hashCodeandequals.The only drawback of delegating to
Arrays.hashCode(Object[])may be that sometimes it may be too expensive from the performance point of view.For example, in your case, this would be a much better hash method for either Teacher or Student.