HashSet

OpenJDK 源代码阅读之 HashSet


概要

  • 类继承关系
1
2
3
4
java.lang.Object
java.util.AbstractCollection<E>
java.util.AbstractSet<E>
java.util.HashSet<E>
  • 定义
1
2
3
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable
  • 要点
  1. 不保证元素次序,甚至不保证次序不随时间变化
  2. 基本操作(add, remove, contains, size)常量时间
  3. 迭代操作与当前元素个数加底层容量大小成正比
  4. 不保证同步

思考

  • 总体实现

底层是用 HashMap 实现的,Set 中的数据是 HashMapkey,所有的 key 指向同一个 value, 此 value 定义为:

1
2
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();

再看一下 add,大概就能明白了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
  • load factor
1
2
3
4
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}

初始化中,注意使用的 HashMap 的 load factor 设置为 0.75,如果太小,就设置成 16.

HashSet 并没有什么特别之处,几乎没有自己特有的实现,都是调用 HashMap 的方法实现相应的功能。

热评文章