Esta es una clase interna de HashMap, que se utiliza para almacenar todos los valores del mapa a través de EntrySet. ¿Por qué podemos usar Iterator para recorrer los datos del mapa? La razón es que existe esta clase interna, EntrySet ---> AbstractSet -> Set -> Colección -> Iterador; (-> indica relación de herencia o realización)
De esta manera, podemos iterar el valor de HashMap a través de Iterator
// 内部内,EntrySet集合
final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
// 集合的大小
public final int size() { return size; }
// 清空数据
public final void clear() { HashMap.this.clear(); }
// 返回迭代器
public final Iterator<Map.Entry<K,V>> iterator() {
return new EntryIterator();
}
// 判断是否包含传入 的key
public final boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Node<K,V> candidate = getNode(hash(key), key);
return candidate != null && candidate.equals(e);
}
// 通过传入 的数据,移除对应的数据
public final boolean remove(Object o) {
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
Object key = e.getKey();
Object value = e.getValue();
return removeNode(hash(key), key, value, true, true) != null;
}
return false;
}
//
public final Spliterator<Map.Entry<K,V>> spliterator() {
return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);
}
// 对应集合进行遍历,对其中的数据 进行操作
public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
Node<K,V>[] tab;
if (action == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next)
action.accept(e);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
}
Código de prueba iterativo:
Iterator<Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
String key = entry.getKey();
System.out.println(key);
System.out.println(entry.getValue());
System.out.println(entry.hashCode());
}