在查看覆盖hashCode()的不同选项时,我被引导到Google的guava-libraries(
javadoc)中的Objects.hashCode(Object []). javadoc声明它委托给Arrays.hashCode(Object []).在许多不同的对象类型中使用此方法是否安全?这不容易发生哈希冲突,或者这不仅仅是因为容器通常只包含一种类型的对象?
举个简单的例子,考虑以下类,
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"); } } }
输出:
studentHash=108322 teacherHash=108322 hash codes match
对象是两种不同的类型,但生成相同的哈希码.这不是问题吗?我应该将类作为第一个参数传入以防止此冲突吗?例如,
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); } }
这就是javadoc警告只为这个方法提供单个对象的原因吗?来自javadoc,
Warning: When a single object is supplied,the returned hash code does not equal the hash code of that object.
解决方法
当2种不同类型的2个不同对象具有相同的哈希码时,这不是问题.
希望,当您打算构建HashMap时,您不会将学生和教师作为该地图的关键.即使在你想要做HashMap< Object,Object>的情况下也是如此.你会好的,因为
assertFalse( new Teacher( "John Smith" ).equals( new Student( "John Smith" ) );
这就是重写hashCode和equals的重要原因.
委托给Arrays.hashCode(Object [])的唯一缺点可能是,从性能的角度来看,有时它可能太昂贵了.
例如,在您的情况下,对于教师或学生来说,这将是一个更好的哈希方法.
@Override public int hashCode() { return name.hashCode(); }