一、HashSet 概述
-
HashSet 实现了 Set 接口。
-
HashSet 基于 HashMap 来实现,是一个不允许有重复元素的集合。
-
HashSet 允许有 null 值。
-
HashSet 是无序的,即不会记录插入的顺序。
-
HashSet 不是线程安全的。
二、HashSet 的使用
2.1 创建
import java.util.HashSet;
HashSet<T> newSet = new HashSet<T>();
2.2 添加元素
set无重复元素的特性,重复添加同值只存放一个。
newSet.add("hello");
2.3 删除元素
newSet.remove("hello");
2.4 是否包含某元素
boolean newSet.contains(T t)
2.5 获取大小
newSet.size();
2.6 遍历集合
可以使用for-each遍历元素
for(T t : newSet) {
System.out.println(t);
}
2.7 清空集合
newSet.clear();
三、HashSet LinkedHashSet 和 TreeSet 三者的对比
1、HashSet、LinkedHashSet 和 TreeSet 都是 Set 接口的实现类,都能保证元素唯一,并且都不是线程安全的。
2、HashSet、LinkedHashSet 和 TreeSet 的主要区别在于底层数据结构不同。
-
HashSet 的底层数据结构是哈希表(基于 HashMap 实现)。
-
LinkedHashSet 的底层数据结构是链表和哈希表,元素的插入和取出顺序满足 FIFO。
-
TreeSet 底层数据结构是红黑树,元素是有序的,排序的方式有自然排序和定制排序。
3、底层数据结构不同又导致这三者的应用场景不同。
-
HashSet 用于不需要保证元素插入和取出顺序的场景,
-
LinkedHashSet 用于保证元素的插入和取出顺序满足 FIFO 的场景,
-
TreeSet 用于支持对元素自定义排序规则的场景。
四、源码分析 HashSet 添加过程
HashSet 内部使用 HashMap 来存放数据,HashSet 元素值放入 HashMap 的 key 里,由 HashMap key的唯一性,保证了 HashSet 元素的唯一性。
内部HashMap 的 value 存放的值可以理解为一个常量,final Object PRESENT = new Object()。
//底层使用了HashMap存储数据。
private transient HashMap<E,Object> map;
//用来填充底层数据结构HashMap中的value,因为HashSet只用key存储数据。
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}