1、HashSet主要的成员变量及构造方法2、add添加内容3、contains是否包含某个键4、remove移除节点5、clear清空
1、HashSet主要的成员变量及构造方法public class HashSetextends AbstractSet implements Set , Cloneable, java.io.Serializable { // 存储数据 private transient HashMap map; // 该变量无变化 private static final Object PRESENT = new Object(); 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); } ...................... }
从上面的构造方法可以看出,HashSet初始化创建的实例为HashMap或者linkedHashMap,而且从源码看出创建的实例功能方法调用还是其实例对应方法的调用
2、add添加内容// HashMap中的内部类Node static class Node3、contains是否包含某个键implements Map.Entry { final int hash; final K key; V value; Node next; Node(int hash, K key, V value, Node next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } ....................... } // 添加方法 public boolean add(E e) { return map.put(e, PRESENT)==null; } // HashMap中的put方法 public V put(K key, V value) { return putVal(hash(key), key, value, false, true); } // HashMap中的putVal方法,添加内容 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node [] tab; Node p; int n, i; // 先赋值在判断 if ((tab = table) == null || (n = tab.length) == 0) // 第一次添加元素前,需要获取初始化获取容量 n = (tab = resize()).length; // 先赋值,判断第一个节点的元素是否为null if ((p = tab[i = (n - 1) & hash]) == null) // 没有内容的时候直接添加 tab[i] = newNode(hash, key, value, null); else { Node e; K k; // 判断第一个节点的键的hash值,键名是否不为空,是否相等 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; // 判断p变量是不是TreeNode的实例 else if (p instanceof TreeNode) e = ((TreeNode )p).putTreeval(this, tab, hash, key, value); else { for (int binCount = 0; ; ++binCount) { // 判断当前节点的下一个节点是否为空 if ((e = p.next) == null) { // 将新添加的节点的内容赋值给当前节点的p.next属性 p.next = newNode(hash, key, value, null); if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } if (e != null) { // existing mapping for key V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
// HashMap中的内部类Node static class Node4、remove移除节点implements Map.Entry { final int hash; final K key; V value; Node next; Node(int hash, K key, V value, Node next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } ....................... } public boolean contains(Object o) { return map.containsKey(o); } // HashMap中的containsKey方法 public boolean containsKey(Object key) { return getNode(hash(key), key) != null; } // HashMap中的getNode方法 final Node getNode(int hash, Object key) { Node [] tab; Node first, e; int n; K k; // 先赋值判断 if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { // 检查第一个节点 if (first.hash == hash && // always check first node ((k = first.key) == key || (key != null && key.equals(k)))) return first; // 检查下一个节点 if ((e = first.next) != null) { if (first instanceof TreeNode) return ((TreeNode )first).getTreeNode(hash, key); // 当前节点的指向的下一个节点不为null时,执行循环查找 do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) return e; } while ((e = e.next) != null); } } return null; }
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
// HashMap中的remove方法
public V remove(Object key) {
Node e;
return (e = removeNode(hash(key), key, null, false, true)) == null ?
null : e.value;
}
// HashMap中的removeNode方法
final Node removeNode(int hash, Object key, Object value,
boolean matchValue, boolean movable) {
Node[] tab; Node p; int n, index;
// 先赋值再判断
if ((tab = table) != null && (n = tab.length) > 0 &&
(p = tab[index = (n - 1) & hash]) != null) {
Node node = null, e; K k; V v;
// 判断当前节点的属性是否相等
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
node = p;
// 判断当前节点指向的下一个节点是否为null
else if ((e = p.next) != null) {
if (p instanceof TreeNode)
node = ((TreeNode)p).getTreeNode(hash, key);
else {
do {
// 判断当前节点的指向的下一个节点的属性与需要查询的属性是否相等
if (e.hash == hash &&
((k = e.key) == key ||
(key != null && key.equals(k)))) {
//找到了,当前节点的指向的下一个节点,赋值给变量node
node = e;
break;
}
// 没有找到,当前节点的指向的下一个节点,赋值给当前节点
p = e;
} while ((e = e.next) != null);
}
}
// 判断node变量是否为null
if (node != null && (!matchValue || (v = node.value) == value ||
(value != null && value.equals(v)))) {
if (node instanceof TreeNode)
((TreeNode)node).removeTreeNode(this, tab, movable);
// 判断是否相等
else if (node == p)
tab[index] = node.next;
else
p.next = node.next;
++modCount;
--size;
afterNodeRemoval(node);
return node;
}
}
return null;
}
5、clear清空
public void clear() {
map.clear();
}
// HashMap中的clear方法
public void clear() {
Node[] tab;
modCount++;
if ((tab = table) != null && size > 0) {
size = 0;
for (int i = 0; i < tab.length; ++i)
tab[i] = null;
}
}



