HashSet是Set集合类的子类,Set集合都有个共同特点是元素是不重复的,无序的(添加和取出的顺序不一定一样),非同步的。
HashSet的底层数据结构就是Hash值组成的Hash表
而HashSet就是通过HashCode和equals方法来判断元素是否重复
当一个元素添加到HashSet集合中时,会自动调用HashCode方法算出元素对象的Hash值,也就是地址值,从而找到元素存放的位置,
自动把当前要添加的元素和集合里的元素比较,如果Hash值不同,就会存到相应的地址位置,如果Hash值相同,就会调用equals方法(继承的Object类的)
来比较元素对象是否相同,如果不是同一个对象,那么就会添加到Hash值相同的那个元素位置底下顺延,
如果是同一个对象,即HashCode和equals方法返回结果都为true时,也就是两个条件都成立,那么就会视为重复元素,
add方法添加元素时就会返回false,也就不会添加成功,这种方式就保证了元素的唯一性。
但是往往用到数据结构是hash表的集合,都要覆写HashCode和equals方法,自定义算出HashCode的条件和判断对象是否相同的条件,因为一般继承过来的方法
往往不是你想要的。
比如将同姓名同年龄的人视为重复元素,以这个为条件的话就必须要覆写HashCode和equals方法,代码如下:- import java.util.*;
- class Person
- {
- private String name;
- private int age;
- Person(String name,int age)
- {
- this.name = name;
- this.age = age;
- }
- public boolean equals(Object obj)
- {
- if(!(obj instanceof Person))
- throw new ClassCastException("不是Person类");
- Person p = (Person)obj;
- return this.name.equals(p.name) && this.age == p.age;
- }
- public int hashCode()
- {
- return name.hashCode()+age;
- }
- public void setName(String name)
- {
- this.name = name;
- }
- public String getName()
- {
- return name;
- }
- public void setAge(int age)
- {
- this.age = age;
- }
- public int getAge()
- {
- return age;
- }
- }
- class HashSetTest
- {
- public static void main(String[] args)
- {
- HashSet<Person> hs = new HashSet<Person>();
- hs.add(new Person("zhangsan",23));
- hs.add(new Person("lisi",12));
- hs.add(new Person("wangwu",21));
- hs.add(new Person("zhangsan",23));
- hs.add(new Person("zhouming",14));
- Iterator<Person> it = hs.iterator();
- while (it.hasNext())
- {
- Person p = it.next();
- System.out.println(p.getName()+"..."+p.getAge());
- }
- }
- }
复制代码 通过自定义条件覆写了Hashcode和equals方法
因为集合中已经存在了姓名是zhangsan,23岁的人,再存zhangsan,23就添加失败,这样就保证了元素的唯一性
楼主有空把HashSet集合用代码实践下,就会慢慢领悟到HashCode的作用了。 |