看了下HashSet.java得源码,发现主要是基于HashMap来实现得,底层才用HashMap得操作数据。
构造函数
public HashSet() {
this(new HashMap<E, HashSet<E>>());
}
/**
* Constructs a new instance of {@code HashSet} with the specified capacity.
*
* @param capacity
* the initial capacity of this {@code HashSet}.
*/
public HashSet(int capacity) {
this(new HashMap<E, HashSet<E>>(capacity));
}
/**
* Constructs a new instance of {@code HashSet} with the specified capacity
* and load factor.
*
* @param capacity
* the initial capacity.
* @param loadFactor
* the initial load factor.
*/
public HashSet(int capacity, float loadFactor) {
this(new HashMap<E, HashSet<E>>(capacity, loadFactor));
}
/**
* Constructs a new instance of {@code HashSet} containing the unique
* elements in the specified collection.
*
* @param collection
* the collection of elements to add.
*/
public HashSet(Collection<? extends E> collection) {
this(new HashMap<E, HashSet<E>>(collection.size() < 6 ? 11 : collection
.size() * 2));
for (E e : collection) {
add(e);
}
}
可以看到全都是才用HashMa来存储数据得。
对于添加,删除等操作,也是直接操作HashMap来实现。
/**
* Adds the specified object to this {@code HashSet} if not already present.
*
* @param object
* the object to add.
* @return {@code true} when this {@code HashSet} did not already contain
* the object, {@code false} otherwise
*/
@Override
public boolean add(E object) {
return backingMap.put(object, this) == null;
}
/**
* Removes all elements from this {@code HashSet}, leaving it empty.
*
* @see #isEmpty
* @see #size
*/
@Override
public void clear() {
backingMap.clear();
}
如果此 set 中尚未包含指定元素,则添加指定元素。更确切地讲,如果此 set 没有包含满足(e==null ? e2==null : e.equals(e2)) 的元素 e2,则向此 set 添加指定的元素 e。如果此 set 已包含该元素,则该调用不更改 set 并返回 false。但底层实际将将该元素作为 key 放入 HashMap。思考一下为什么?
由于 HashMap 的 put() 方法添加 key-value 对时,当新放入 HashMap 的 Entry 中 key 与集合中原有 Entry 的 key 相同(hashCode()返回值相等,通过 equals 比较也返回 true),新添加的 Entry 的 value 会将覆盖原来 Entry 的 value(HashSet 中的 value 都是PRESENT),但 key 不会有任何改变,因此如果向 HashSet 中添加一个已经存在的元素时,新添加的集合元素将不会被放入 HashMap中,原来的元素也不会有任何改变,这也就满足了 Set 中元素不重复的特性。
通过源码解读,如果对HashMap 比较熟悉,那么理解HashSet 就很容易了。
本文解读了 HashSet.java 源码,发现其主要基于 HashMap 实现,构造函数用 HashMap 存储数据,添加、删除等操作也直接操作 HashMap。向 HashSet 添加已存在元素时,因 HashMap 特性,新元素不会放入,满足 Set 元素不重复特性,熟悉 HashMap 就易理解 HashSet。

264

被折叠的 条评论
为什么被折叠?



