我们知道比较两个对象相等的方法是重写这个对象的equals和hashCode方法。
但是这个hashCode方法到底有什么作用呢。我只重写equals方法到底行不行呢。
我们新建一个类看一下
public class Person {
private int age;
private String name;
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// @Override
// public int hashCode() {
// final int prime = 31;
// int result = 1;
// result = prime * result + age;
// result = prime * result + ((name == null) ? 0 : name.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;
final Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
这个类只重写了equals方法,测试一下
public static void main(String[] args) {
Collection<Person> list = new ArrayList<Person>();
Collection<Person> set = new HashSet<Person>();
CoTest ct = new CoTest();
list = ct.addEle(list);
System.out.println("ArrayList size == " + list.size());
set = ct.addEle(set);
System.out.println("HashSet size == " + set.size());
}
private Collection<Person> addEle(Collection<Person> col) {
Person p1 = new Person(1, "a");
Person p2 = new Person(1, "a");
Person p3 = new Person(2, "a");
Person p4 = new Person(3, "a");
col.add(p1);
col.add(p2);
col.add(p3);
col.add(p4);
return col;
}
打印出了如下的结果
ArrayList size == 4
HashSet size == 4
证明p1和p2两个对象还是不相等的
当我们把hashCode注释打开再运行一次
ArrayList size == 4
HashSet size == 3
证明了p1和p2两个对象已经相等
hashCode是一种算法,像这种HashSet HashMap基于哈希表存储的集合类型每次往里存储一个元素都要根据哈希算法计算出这个对象的哈希值,相同哈希值的元素被存储在以这个哈希值命名的一个空间里面,以后再往里面存储元素的话就可以直接根据这个元素的哈希值找到对应的空间判断这两个元素是否相等,这样存储的效率就会显著提高。
刚才那个问题,没有重写hashCode,那么元素的值就会没有规则的存放,把这个元素放到任意一个空间里如果没有则判断为不相等,其实相同的元素可能存在别的空间里。
好了,总结一下,如果为某个类编写了equals方法,那么同时应该编写hashCode方法,如果不编写hashCode方法,在使用基于哈希表结构的集合时就会发生意想不到的结果,为了避免这些问题,你应该谨记这条最佳实践。