HashSet最全详解(特点原理及使用示例)

HashSet最全详解(特点原理及使用示例)-mikechen

HashSet定义

HashSet是Set接口的一个实现类,其实现类除HashSet之外,还有TreeSet,并继承了Collection,下面是结构图:

HashSet最全详解(特点原理及使用示例)-mikechen

public class HashSet
    extends AbstractSet
    implements Set, Cloneable, java.io.Serializable
{}

HashSet是Java集合框架最常用实现类,是其Set经典实现。

 

HashSet特点

HashSet有一些典型的特征,大致分为如下6点:

  1. HashSet底层是包装了一个HashMap实现的;
  2. 底层数据结构是数组 链表 红黑树;
  3. HashSet不保证顺序,且非线程安全的;
  4. HashSet实现了Set Interface,所以不允许重复值;
  5. 在HashSet中插入的对象不保证以相同顺序插入;
  6. HashSet中允许使用NULL元素;

 

HashSet实现原理

对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,如下源码:

private transient HashMap<E,Object> map;

   // Dummy value to associate with an Object in the backing Map
   private static final Object PRESENT = new Object();

   /**
    * Constructs a new, empty set; the backing HashMap instance has
    * default initial capacity (16) and load factor (0.75).
    */
   public HashSet() {
       map = new HashMap<>();
   }
   public boolean add(E e) {
       // 使用 HashMap 的实例来存储
       return map.put(e, PRESENT)==null;
   }

HashSet最全详解(特点原理及使用示例)-mikechen

在JDK 8版本中,对于哈希表的实现做了一些改进,通过数组 链表 红黑树实现。

当某个桶经常发生哈希冲突时,该链表长度将会变的非常长,下一次新对象将必须依次比较该桶中的所有对象,耗费大量时间降低性能。

为此当桶中对象数量超过8个时,在JDK 8 中会将该链表转换为红黑树(如上图黑色桶所示)进行存储。此举将大大减少新对象在该桶的比较次数,提高性能。

 

HashSet使用示例

1.添加元素

HashSet新增元素时,如果元素已经存在,它就不会再新增。

示例如下:

import java.util.HashSet;

public class HashSetIntro {
    public static void main(String[] args) {
        //声明字符串链表
        HashSet lang = new HashSet<>();

        //新增元素
        lang.add("中文");
        lang.add("英文");
        lang.add("法文");

        //存在元素不再新增
        lang.add("法文");
        System.out.println(lang);

    }
}

 

2.删除元素

import java.util.HashSet;

public class HashSetIntro {
    public static void main(String[] args) {
        //声明字符串链表
        HashSet lang = new HashSet<>();
        //新增元素
        lang.add("中文");
        lang.add("英文");
        
        //删除单个元素
        lang.remove("英文");
        System.out.println(lang);

    }
}

 

3.访问元素

  import java.util.HashSet;

public class RunoobTest {
    public static void main(String[] args) {
    HashSet sites = new HashSet();
        sites.add("taobao");
        sites.add("mikechen");
        sites.add("baidu");
    
        sites.add("mikechen");     // 重复的元素不会被添加
        for (String i : sites) {
            System.out.println(i);
        }
    }
}

 

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法