我们开发时写一个类,默认继承Object类,Object类的equals方法是比较是否指向同一个对象(地址是否相同),
Object类 的hashcode方法返回的对象内存地址的值,
一个类只重写了equals方法,不重写hashcode,那么对象equals为true(比较内容),但是hashcode为false(因为不同对象,地址不同)
那么对于hash散列表结构的容器集合,就会出现问题。
例如:有类Person如下,只重写了equals方法
1 public class Person{ 2 private int id; 3 private String name; 4 5 public Person(int id,String name) { 6 this.id = id; 7 this.name = name; 8 } 9 10 public int getId() { 11 return id; 12 } 13 public void setId(int id) { 14 this.id = id; 15 } 16 public String getName() { 17 return name; 18 } 19 public void setName(String name) { 20 this.name = name; 21 } 22 23 @Override 24 public boolean equals(Object obj) { 25 if (this == obj) 26 return true; 27 if (obj == null) 28 return false; 29 if (getClass() != obj.getClass()) 30 return false; 31 Person other = (Person) obj; 32 if (id != other.id) 33 return false; 34 if (name == null) { 35 if (other.name != null) 36 return false; 37 } else if (!name.equals(other.name)) 38 return false; 39 return true; 40 } 41 42 }
测试如下:
1 public static void main(String[] args) { 2 Person p1 = new Person(1,"tom"); 3 Person p2 = new Person(1,"tom"); 4 5 System.out.println("p1与p2是否相等:"+p1.equals(p2)); 6 System.out.println("p1 hashcode值:"+p1.hashCode()); 7 System.out.println("p2 hashcode值:"+p2.hashCode()); 8 9 // hashset集合值不允许重复 10 Set<Person> set = new HashSet<>(); 11 set.add(p1); 12 set.add(p2); 13 System.out.println(set); 14 }
运行结果如下:
因为hashmap,hashset等散列数据结构,会根据hashcode值计算存放在数组中桶的位置,上面两个对象的hashcode不同,所以
就会存放在数值中的不同位置,这样就会出现一个错误的结果。
如果重写hashcode方法呢?
运行结果如下:
总结:新建一个类,重写equals的同时一定要重写hashcode方法,否则使用散列表数据结构的容器时就会出现问题,
在重写equals和hashcode后,可以保证equals比较为true,hashcode比较一定为true,但是hashcode相同的两个对象,
equals不一定相同。