HashSet通过两个方法来判断一个元素的唯一性,他们都是object的方法,一个是hashCode()与equals()方法
public class HashSetDome {
public static void main(String[] args) {
HashSet hs = new HashSet();
Person p1 = new Person("a1", 11);
Person p2 = new Person("a1", 11);
Person p3 = new Person("a1", 11);
hs.add(p1);
hs.add(p2);
hs.add(p3);
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+"....."+p.getAge());
}
}
}
class Person{
private String name;
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;
}
private int age;
public Person(String name ,int age){
this.name = name;
this.age = age;
}
}
以上代码的结果为:
a1.....11
a1.....11
a1.....11
可以看出来相同的元素还是存入了,这是为什么呢?因为HashSet会首先根据哈希值来判断唯一性,因为p1,p2,p3都是new的所以哈希值不是相同的,我们可以通过重写hashCode()更改Person的地址值看看结果
public class HashSetDome {
public static void main(String[] args) {
HashSet hs = new HashSet();
Person p1 = new Person("a1", 11);
Person p2 = new Person("a1", 11);
Person p3 = new Person("a1", 11);
hs.add(p1);
hs.add(p2);
hs.add(p3);
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+"....."+p.getAge());
}
}
}
class Person{
private String name;
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;
}
private int age;
public Person(String name ,int age){
this.name = name;
this.age = age;
}
public int hashCode(){
return 60;
}
}
结果:
a1.....11
a1.....11
a1.....11
我重写了hashCode()了方法可是结果还是没变,我把equals()方法也重写了在来看结果
public class HashSetDome {
public static void main(String[] args) {
HashSet hs = new HashSet();
Person p1 = new Person("a1", 11);
Person p2 = new Person("a1", 11);
Person p3 = new Person("a1", 11);
hs.add(p1);
hs.add(p2);
hs.add(p3);
Iterator it = hs.iterator();
while(it.hasNext()){
Person p = (Person)it.next();
System.out.println(p.getName()+"....."+p.getAge());
}
}
}
class Person{
private String name;
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;
}
private int age;
public Person(String name ,int age){
this.name = name;
this.age = age;
}
public int hashCode(){
return 60;
}
public boolean equals(Object obj){
if(!(obj instanceof Person)){
return false;
}
Person p = (Person)obj;
return this.name.equals(p.name)&&this.age == p.age;
}
}
结果:
a1.....11
可以看见我添加的3个相同的元素只剩一个了,所以证明了HashSet是通过hashCode()与equals()方法一起判断一个元素是否相同
这里还有一个顺序问题,就是HashSet首先判断hashCode()的值是否相同,如果相同则继续判断equals(),所以我们可以根据这个性质来优化程序
public int hashCode(){
return this.name.hashCode()+age*28;(这里*28是为了更好的确保唯一性)
}
可以让每个对象的哈希值保证唯一性,这样就可以一次比较出来,因为当哈希值能已经比较出两个对象是否相同时,程序就不会在执行一次equals()方法所以这样效率就提高了