Skip to content

Commit 0208fb1

Browse files
committed
HashSet 源码赏析
1 parent 4f059d0 commit 0208fb1

File tree

1 file changed

+116
-1
lines changed

1 file changed

+116
-1
lines changed

docs/JDK/collection/HashSet.md

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,116 @@
1-
努力编写中...
1+
HashSet 本身并没有什么特别的东西,它提供的所有集合核心功能,都是基于HashMap来实现的。如果了解HashMap源码的实现,HashSet 源码看起来跟玩一样。我的博客中有专门分析HashMap源码的文章,不熟悉的请自行翻阅。
2+
3+
HashSet 的特点如下:
4+
- 内部使用HashMap的key存储元素,以此来保证**元素不重复**
5+
- HashSet是无序的,因为HashMap的key是**无序**的;
6+
- HashSet中允许有一个null元素,因为HashMap允许key为null;
7+
- HashSet是**非线程安全**的。
8+
9+
```java
10+
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
11+
static final long serialVersionUID = -5024744406713321676L;
12+
13+
// 基于HashMap实现
14+
private transient HashMap<E,Object> map;
15+
16+
// 只需要用到HashMap中key唯一的特性,所以value全部使用同一个 Object实例填充,节省内存空间
17+
private static final Object PRESENT = new Object();
18+
19+
/**
20+
* 实例化 HashSet 的时候,初始化内部的 HashMap
21+
*/
22+
public HashSet() {
23+
map = new HashMap<>();
24+
}
25+
26+
/**
27+
* 根据一个集合实例,实例化 HashSet
28+
*/
29+
public HashSet(Collection<? extends E> c) {
30+
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
31+
addAll(c);
32+
}
33+
34+
/**
35+
* 根据初始容量和扩容因子实例化 HashSet,减少rehash频率,提升性能,原理与HashMap相同
36+
*/
37+
public HashSet(int initialCapacity, float loadFactor) {
38+
map = new HashMap<>(initialCapacity, loadFactor);
39+
}
40+
41+
/**
42+
* 同上
43+
*/
44+
public HashSet(int initialCapacity) {
45+
map = new HashMap<>(initialCapacity);
46+
}
47+
48+
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
49+
map = new LinkedHashMap<>(initialCapacity, loadFactor);
50+
}
51+
52+
/**
53+
* 返回迭代器,用于迭代
54+
* 下面所有的功能都是基于 HashMap 来实现的
55+
*/
56+
public Iterator<E> iterator() {
57+
return map.keySet().iterator();
58+
}
59+
60+
/**
61+
* 元素个数
62+
*/
63+
public int size() {
64+
return map.size();
65+
}
66+
67+
/**
68+
* 是否为空
69+
*/
70+
public boolean isEmpty() {
71+
return map.isEmpty();
72+
}
73+
74+
/**
75+
* 是否包含给定元素
76+
*/
77+
public boolean contains(Object o) {
78+
return map.containsKey(o);
79+
}
80+
81+
/**
82+
* 添加元素,如果 Set集合中未包含该元素,返回true
83+
*/
84+
public boolean add(E e) {
85+
return map.put(e, PRESENT)==null;
86+
}
87+
88+
/**
89+
* 删除元素,如果Set集合包含该元素,返回true
90+
*/
91+
public boolean remove(Object o) {
92+
return map.remove(o)==PRESENT;
93+
}
94+
95+
/**
96+
* 清除元素
97+
*/
98+
public void clear() {
99+
map.clear();
100+
}
101+
102+
/**
103+
* 浅克隆
104+
*/
105+
@SuppressWarnings("unchecked")
106+
public Object clone() {
107+
try {
108+
HashSet<E> newSet = (HashSet<E>) super.clone();
109+
newSet.map = (HashMap<E, Object>) map.clone();
110+
return newSet;
111+
} catch (CloneNotSupportedException e) {
112+
throw new InternalError(e);
113+
}
114+
}
115+
}
116+
```

0 commit comments

Comments
 (0)