文章目录
HashSet 简介
HashSet是一个没有重复元素的集合,是基于HashMap实现的,因此具有良好的存取和查找性能。但它不保证集合的迭代顺序,特别是它不保证该顺序恒久不变。
HashSet具体以下特点:
- 不保证元素的迭代顺序(HashMap的key是无序的);
- 元素不可重复(HashSet内部使用HashMap的key存储元素,以此来保证元素不重复);
- 非线程安全的集合;
- 集合允许使用null元素;
- HashSet是没有get()方法。
一、实现原理
HashSet底层是基于HashMap实现的,HashSet的元素都存储在HashMap的key上面,value上只是存储一个默认的静态的Object对象常量(PRESENT)。
由此可见,HashSet底层数据结构也是:数组+链表+红黑树。
二、源码分析
2.1 继承与实现关系
- 继承了AbstractSet类,并实现了Set接口,意味着它是Set接口的具体实现,而且遵循着Set的操作规范;
- 实现了Cloneable接口,标记着其可以被克隆复制;
- 实现了Serializable接口,意味着它支持序列化。
2.2 重要成员信息
- map:用来保存HashSet中所有元素的容器,可以看出,其是依赖于HashMap实现的;
- PRESENT:虚拟对象值,用来作为value放到map中。
2.3 构造方法
构造方法都是调用HashMap对应的构造方法。
注意:最后一个构造方法有点特殊,它不是public的,意味着它只能被同一个包或者子类调用,它是LinkedHashSet专属的方法。
2.4 重要方法
2.4.1 添加
调用的是HashMap的put方法,key为HashSet存入的元素,value是固定不变的Object类型的常量对象PRESENT。
2.4.2 删除
调用的是HashMap的移除元素方法。
三、对应线程安全实现
3.1 Collections 同步方法
synchronizedSet(Set s):返回一个synchronizedSet类型的线程安全的集合类。其对部分操作加上了synchronized关键字以保证线程安全。
使用方法:Collections.synchronizedSet(new HashSet());
3.2 CopyOnWriteArraySet
- CopyOnWriteArraySet是用CopyOnWriteArrayList实现的;
- CopyOnWriteArraySet是有序的,因为底层其实是数组;
- CopyOnWriteArraySet是并发安全的,而且实现了读写分离;
- CopyOnWriteArraySet通过调用CopyOnWriteArrayList的addIfAbsent()方法来保证元素不重复;