public class Test {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("1");
set.add("1");
set.add("2");
set.remove("1");
set.remove("0");
System.out.println(set.size());
}
}
上述代码运行结果为 :1
HashSet中的remove方法
public boolean remove(Object o) { return map.remove(o)==PRESENT; }
由上面底层源码可知,HashSet中remove方法实际上是调用了HashMap中的remove方法:
public V remove(Object key) { Node<K,V> e; return (e = removeNode(hash(key), key, null, false, true)) == null ? null : e.value; }
这里调用了removeNode()方法 和 hash()方法:
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
final Node<K,V> removeNode(int hash, Object key, Object value, boolean matchValue, boolean movable) { Node<K,V>[] tab; Node<K,V> p; int n, index; if ((tab = table) != null && (n = tab.length) > 0 && (p = tab[index = (n - 1) & hash]) != null) { Node<K,V> node = null, e; K k; V v; if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) node = p; else if ((e = p.next) != null) { if (p instanceof TreeNode) node = ((TreeNode<K,V>)p).getTreeNode(hash, key); else { do { if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) { node = e; break; } p = e; } while ((e = e.next) != null); } } if (node != null && (!matchValue || (v = node.value) == value || (value != null && value.equals(v)))) { if (node instanceof TreeNode) ((TreeNode<K,V>)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; }
具体分析执行过程:
由上面的博客《HashSet中的add方法(对集合底层的分析)》----->https://blog.csdn.net/qq_40831381/article/details/90119935中可知,程序成功将一个字符串“1”和一个字符串“2”添加到了set中(不能重复添加)------>
执行第一个remove方法:set.remove("1");具体过程:.
参数列表中hash值是hash(key)方法中key调用的hashCode执行第一个remove方法时,key的值是字符串“1”,在table成员变量中,由于前面成功添加了两个字符串,table已经从null变成了有值的了,tab.length=16----->执行:if ((tab = table) != null && (n = tab.length) > 0 && (p = tab[index = (n - 1) & hash]) != null)成立,继续执行---->if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))),p是参数中Node<K,V> p声明的一个局部变量, 由于是key的值是String类型的,equals比较的是内容,所以返回的是true,所以继续执行,可以成功删除
执行第二个remove方法:set.remove("2");具体过程:
key的值是字符串“2”---->执行:if ((tab = table) != null && (n = tab.length) > 0 && (p = tab[index = (n - 1) & hash]) != null)成立,继续执行---->if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))不成立,然后执行 else if ((e = p.next) != null)---->if (p instanceof TreeNode)不符合,所有执行else----->然后继续循环遍历set表中的值,与key值比较,看是否一致,没有一致的,所有不能删除成功。