package cn.itcast.bean.person;
public class Person {
private String name;
public Person() {
super();
}
@Override
public int hashCode() {
return name.hashCode()+age*39;//name是String类型,String类型有自己的hashCode方法,其返回值就是int,那么正好姓名哈希值+年龄,可以确定一个人的哈希值。
}//乘上39原因:假设zhangsan姓名哈希值20,年龄哈希值40,相加为60,;lisi姓名哈希值30,年龄哈希值30,相加为60,明明不同对象却认为同一个哈希地址,所以乘以39保证一个对象哈希值的唯一性。
@Override
public boolean equals(Object obj) {//这里equals方法是Person类的方法
/*
* Person p = new Person();
* hs.add(p);
* hs.add(p);
* 为避免出现以上情况,所以加上下面健壮性判断。
*/
if(this==obj)
return true;
/*
* 如果传一个非Person类进来怎么办?所以加入下面健壮性判断,直接抛异常
*/
if(!(obj instanceof Person))
throw new ClassCastException("类型不匹配");
Person p = (Person)obj;//先将Object类型对象强转为Person类型
return this.name.equals(p.name)&&this.age==p.age;//这行的equals方法是String类自己的equals方法
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
==============================================================分割线=================================================================
package cn.itcast.hashset.test;
import java.util.HashSet;
import java.util.Iterator;
import cn.itcast.bean.person.Person;
public class HashSetTest {
public static void main(String[] args) {
/*
* 往hashSet集合中存储Person对象,如果姓名和年龄相同,视为同一个人。视为相同元素。
*/
HashSet hs = new HashSet();
hs.add(new Person("lisi4", 24));//调用hashCode方法算存储位置,不需要调用equals方法,因为hashCode结果不同
hs.add(new Person("lisi7", 27));//调用hashCode方法算存储位置,不需要调用equals方法,因为hashCode结果不同
hs.add(new Person("lisi1", 21));//调用hashCode方法算存储位置,不需要调用equals方法,因为hashCode结果不同
hs.add(new Person("lisi9", 29));//调用hashCode方法算存储位置,不需要调用equals方法,因为hashCode结果不同
hs.add(new Person("lisi9", 29));//调用hashCode方法算存储位置,【调用equals方法】,因为hashCode结果与上一个对象相同,equals发现是同一个对象,那么不存
/*
* 【如果在Person中不复写hashCode和equals方法】
* 相同元素为啥会存两次?因为Person继承Object,用的是Object中的hashCode和equals方法,而Object中的equals方法
* 是比较两个对象的地址值,由于都是new对象,都在堆内存中开辟新空间,所以同一个人可以有两个地址,那么该equals
* 方法比较结果不相同地址,即认为是两个不同的元素,所以会出现存入两个lisi9....29。
*/
Iterator it = hs.iterator();
while (it.hasNext()) {
Person p = (Person) it.next();
System.out.println(p.getName() + "...." + p.getAge());
}
}
}