欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

集合之浅谈HashSet

程序员文章站 2022-05-23 14:18:30
...

HashSet的底层存储结构

此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null 元素。
hashSet的继承结构
集合之浅谈HashSet

hashSet的底层结构实现图
集合之浅谈HashSet

HashSet的特性

  • hashSet是唯一的(不重复)此实现是通过重写对象的hashCode与equals方法
1.先计算hash
  int hash = hash(key);
2.根据hash值去散列桶中找链表对应得index
  int i = indexFor(hash, table.length);
3.根据index去遍历链表看是否有相应的对象
  for (Entry<K,V> e = table[i]; e != null; e = e.next) 
4.如果存在对象就判断old 的hash值与new 的hash是否相等
  if(e.hash == hash) {
    if(((k = e.key) == key || key.equals(k)))
      不做处理
    else
      添加
  }else{
    不添加
  }
  • 无序的(存入的顺序与取出的顺序不能保证一致)
  • 线程不安全的(此实现不是同步的)

HasHSet存储自定义的对象示例

定义Student对象:

/**
 * @Description 学生model 根据姓名与年龄来判断是否为同一个学生
 * @Author xiaoqx <aaa@qq.com>
 * @Version V1.0.0
 * @Since 2017/9/25
 */
public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = 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;
    }

    /**
     * 重写hashCode 方法
     * 之所以要乘30
     * 是否防止 age=32 name.hashCode=28   60
     *         age=28 name.hashCode=32   60
     * @return
     */
    public int hashCode(){
        return this.name.hashCode()+this.age*30;
    }

   public boolean equals(Object obj){
        Student s1 = (Student) obj;
        boolean isSame = (this.name.hashCode()+this.age*30)-(s1.name.hashCode()+s1.age*30)==0?true:false;
        if(isSame){
            if(this.name.equals(s1.name))
                return true;
            else
                return false;
        }
        return false;
   }

    @Override
    public String toString() {
        return this.name+":"+age;
    }
}

测试HashSet的存储:


/**
 * @Description 查看HashSet add方法的底层原理。
 *  HashSet中元素是唯一的,hashSet的底层结构是Hash表,hash表是存储     链表的动态数组组成。
 *   1.hashSet.add()先是通过对象的hashCode来判断是否相同,如果相同在通过equals方法来判断
 *  HashSet是无序的(存入的顺序与取出的顺序可能不同)
 *
 * @Author xiaoqx <aaa@qq.com>
 * @Version V1.0.0
 * @Since 2017/9/25
 */
public class HashSetAdd {
    public static void main(String[]args){
        HashSet hashSet = new HashSet();

        Student s1 = new Student("zhangsan",20);
        Student s2 = new Student("wangwu",21);
        Student s3 = new Student("lisi",20);
        Student s4 = new Student("zhangsan",24);
        Student s5 = new Student("zhangsan",20);

        hashSet.add(s1);
        hashSet.add(s2);
        hashSet.add(s3);
        hashSet.add(s4);
        hashSet.add(s5);

        Iterator it = hashSet.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}
输出结果:
    wangwu:21
    zhangsan:24
    lisi:20
    zhangsan:20
相关标签: collection