与List不同,Set中的元素是无序且不重复的。
Set家族
类图(正在绘制中,请稍后…)
Set源码
1 | public interface Set<E> extends Collection<E> { |
遍历Set
Set继承了Collection接口,而Collection接口又继承了Iterable接口,因此可以使用for-each循环、迭代器以及forEach方法(JDK1.8新增)三种方式进行遍历。下面以Set<String>
为例,逐一说明这三种方式。
for-each循环
1 | for (String s : set) { |
迭代器
1 | Iterator<String> iter = set.iterator(); |
forEach方法
1 | set.forEach(e -> { |
HashSet
HashSet使用HashMap实现,从而导致存储在其中的元素是无序且不重复的,它允许值为null(HashMap最多允许一条记录的键为null)。
存储结构
1 | private transient HashMap<E,Object> map; |
构造方法
1 | public HashSet() { |
添加元素
HashSet中的元素实际上就是HashMap中的键,它们对应的值均为同一个对象。
1 | public boolean add(E e) { |
删除元素
1 | public boolean remove(Object o) { |
TreeSet
与HashSet的实现方式类似,TreeSet使用TreeMap实现,从而导致存储在其中的元素是有序且不重复的。此外,它不允许值为null(TreeMap不允许任何记录的键为null)。
存储结构
1 | private transient NavigableMap<E,Object> m; |
构造方法
1 | TreeSet(NavigableMap<E,Object> m) { |
由于TreeSet的添加和删除操作也是直接调用TreeMap的相应方法实现的,因此,这里不再一一列出。
CopyOnWriteArraySet
CopyOnWriteArraySet是基于CopyOnWriteArrayList实现的,存储在其中的元素是有序且不重复的,并且它允许值为null。
存储结构
1 | private final CopyOnWriteArrayList<E> al; |
构造方法
1 | public CopyOnWriteArraySet() { |
添加元素
1 | public boolean add(E e) { |
删除元素
1 | public boolean remove(Object o) { |
实现类比较
实现类 | 实现机制 | 是否允许为null | 是否有序 | 是否线程安全 |
---|---|---|---|---|
HashSet | 基于HashMap | 允许 | 无序 | 线程不安全 |
TreeSet | 基于TreeMap | 不允许 | 有序 | 线程不安全 |
CopyOnWriteArraySet | 基于CopyOnWriteArrayList | 允许 | 有序 | 线程安全 |