浅析JDK1.8 HashSet源码。
写在开篇
HashSet源码比较简单,所以文章就会比较过水。
先简单介绍一下HashSet:
- 实现了Set接口,不允许元素重复
- 底层实现是基于HashMap的,它利用HashMap中的key存储数据,使用成员变量PRESENT来填充value
- 是线程不安全的
类的继承关系
HashSet继承AbstractSet抽象类,实现了Set(规定了Set的操作规范)、Cloneable(可拷贝)、Serializable(可序列化)这几个接口。
1 2 3
| public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
|
成员变量
1 2 3 4 5
| private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
|
构造方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
public HashSet() { map = new HashMap<>(); }
public HashSet(Collection<? extends E> c) { map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); }
public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); }
public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); }
HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<>(initialCapacity, loadFactor); }
|
Set接口的实现
add()
HashSet将添加的元素通过map中的key来保存,当有相同的key时,也就是添加了相同的元素,那么map会讲value给覆盖掉,而key还是原来的key。
1 2 3
| public boolean add(E e) { return map.put(e, PRESENT)==null; }
|
remove()
HashSet通过删除map中key的返回值是否为PRESENT判断set中是否有该值。
1 2 3
| public boolean remove(Object o) { return map.remove(o)==PRESENT; }
|
contains()
直接调用map中containsKey()。
1 2 3
| public boolean contains(Object o) { return map.containsKey(o); }
|
isEmpty()
1 2 3
| public boolean isEmpty() { return map.isEmpty(); }
|
size()
1 2 3
| public int size() { return map.size(); }
|
iterator()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public Iterator<E> iterator() { return map.keySet().iterator(); } public Set<K> keySet() { Set<K> ks = keySet; if (ks == null) { ks = new KeySet(); keySet = ks; } return ks; } private final class KeySet extends AbstractSet<K> { public Iterator<K> iterator() { return newKeyIterator(); } public int size() { return size; } public boolean contains(Object o) { return containsKey(o); } public boolean remove(Object o) { return HashMap.this.removeEntryForKey(o) != null; } public void clear() { HashMap.this.clear(); } } Iterator<K> newKeyIterator() { return new KeyIterator(); } private final class KeyIterator extends HashIterator<K> { public K next() { return nextEntry().getKey(); } }
|
Last updated: