HashMap的迭代器是强一致性的,但是我们又需要在迭代器遍历时删除元素呢? 调用迭代器的remove方法。
public static void useMap(final Map<String,Integer> scores) {
scores.put("WU",19);
scores.put("zhang",14);
scores.put("sun",14);
scores.put("zhou",14);
try {
Iterator<String> iterator = scores.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
if(key.equals("sun")) {
iterator.remove(); // 首先在迭代器中删除这个元素
}
}
iterator = scores.keySet().iterator();
while (iterator.hasNext()) {
String key = iterator.next();
System.out.println(key);
}
}catch (Exception ex) {
System.out.println("fail:" + ex);
}
}
public static void main(String[] args) {
useMap(new HashMap<String, Integer>());
}
/*
zhang
zhou
WU
*/
abstract class HashIterator {
Node<K,V> next; // next entry to return
Node<K,V> current; // current entry
int expectedModCount; // for fast-fail
int index; // current slot
HashIterator() {
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
if (t != null && size > 0) { // advance to first entry
do {} while (index < t.length && (next = t[index++]) == null);
}
}
public final boolean hasNext() {
return next != null;
}
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
public final void remove() {
Node<K,V> p = current;
if (p == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
current = null;
K key = p.key;
//1 会调用HashMap的方法removeNode()进行删除,删除时,HashMap的modCount会增加
removeNode(hash(key), key, null, false, false);
//2 同时更新迭代器的expectedModCount,后续的遍历不会报错
expectedModCount = modCount;
}
}