本系列文章所描述的所有类或接口都是基于 JDK 1.7的源码,在其它 JDK 的实现方式中可能会有所不同。
一、实现方式
HashSet 是 Set 接口的实现,Set 和 List 最明显的区别在于 Set 不允许元素重复,而 List 允许。Set 为了做到不允许元素重复,采用的是基于 HashMap 来实现,HashMap 在后面的系列中会详细说明。
二、创建 HashSet
此时所要做的为创建一个 HashMap 对象。
public HashSet() {
map = new HashMap<>();
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
三、添加元素 add(E)
调用 HashMap 的 put(Object, Object) 方法来完成此操作,将需要增加的元素作为 Map 中的 key,value 则传入一个之前已创建的 Object 对象。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
四、删除元素 remove(E)
调用 HashMap 的 remove(E) 方法来完成此操作。
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
五、判断元素是否存在 contains(E)
调用 HashMap 的 containsKey(E) 方法来完成此操作。
public boolean contains(Object o) {
return map.containsKey(o);
}
六、遍历元素 iterator
调用 HashMap 的 keySet 的 iterator 方法来完成此操作。
HashSet 不支持通过 get(int) 获取指定位置的元素,只能自行通过 iterator 方法来获取。
public Iterator<E> iterator() {
return map.keySet().iterator();
}
七、注意要点
对于 HashSet 而言,最要注意的有以下几点:
- HashSet 基于 HashMap 实现,无容量限制;
- HashSet 是非线程安全的。