在java集合中,我们知道有hashSet、hashMap这两种由散列表构成的集合,这两种集合在add()或者是put()时,虚拟机会先查看添加的元素哈希值是否相等,如果不等,虚拟机则会开辟出一个新的内存空间给这个元素。如果相等的话,虚拟机会继续使用equals()方法比较,如果还是相等那么虚拟机就认为这个元素已经存在,否则会将该元素添加到散列表中。
那么在我们实际编程时,我们会将类似于person对象添加到集合中,但是我们不能因为地址不同就认为两个person对象不是同一个person,实际上我们在添加类似这样的对象时,我们要考虑这些对象逻辑上是否相等,例如:person对象有name属性,我们需要通过name来判断这些person对象是否相同,所以我们就需要重写hashcode()和equals()方法
例如:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
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 (this.getClass() != obj.getClass())
return false;
Person p = (Person) obj;
if (this.name == null) {
if (p.name != null)
return false;
} else if (!this.name.equals(p.name))
return false;
return true;
}
Person person1 = new Person ("123");
Person person2 = new Person ("123");
Set<Person > set = new HashSet<>();
//在不重写hashcoed和equals方法时,会将两对象看成两个不同的元素全部add进去
set.add(person1);//成功
set.add(person2);//成功
//但这里我们认为在逻辑上name不相同的对象才称作不同元素,所以我们就需要重写hashcoed和equals方法
//在重写了两个方法后,我们发现name相同的两个对象只被添加了一次
System.out.println(set.size());//返回1