集合的迭代器遍历中iterator.hasNext()、iterator.next()从字面上不理解,下面从源码解析。
这里以TreeMap为例进行分析。
TreeMap的遍历方式
1、for循环方式
for (Map.Entry entry : treeMap.entrySet()) {
System.out.println(entry);
}
2、迭代器方式
Iterator iterator = treeMap.entrySet().iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
根据TreeMap及Iterator接口源码理解上述疑惑
Jva结合中Iterator接口,接口包含4个方法。
public interface Iterator<E> {
/**
* Returns {@code true} if the iteration has more elements.
* (In other words, returns {@code true} if {@link #next} would
* return an element rather than throwing an exception.)
*
* @return {@code true} if the iteration has more elements
*/
boolean hasNext();
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
E next();
/**
* Removes from the underlying collection the last element returned
* by this iterator (optional operation). This method can be called
* only once per call to {@link #next}. The behavior of an iterator
* is unspecified if the underlying collection is modified while the
* iteration is in progress in any way other than by calling this
* method.
*
* @implSpec
* The default implementation throws an instance of
* {@link UnsupportedOperationException} and performs no other action.
*
* @throws UnsupportedOperationException if the {@code remove}
* operation is not supported by this iterator
*
* @throws IllegalStateException if the {@code next} method has not
* yet been called, or the {@code remove} method has already
* been called after the last call to the {@code next}
* method
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* Performs the given action for each remaining element until all elements
* have been processed or the action throws an exception. Actions are
* performed in the order of iteration, if that order is specified.
* Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(next());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
PrivateEntryIterator是TreeMap的内部抽象类,实现了Iterator接口。
TreeMap中其他类型的Iterator类都继承自PrivateEntryIterator。
/**
* Base class for TreeMap Iterators
*/
abstract class PrivateEntryIterator<T> implements Iterator<T> {
Entry<K,V> next;
Entry<K,V> lastReturned;
int expectedModCount;
PrivateEntryIterator(Entry<K,V> first) {
expectedModCount = modCount;
lastReturned = null;
next = first;
}
//next表示下一个Entry是否为null
public final boolean hasNext() {
return next != null;
}
//作用有二
//1、返回当前的Entry
//2、next引用的移动,移到下一个Entry
final Entry<K,V> nextEntry() {
//拿到上一次的next,也就是当前的Entry
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
//从这里可以看出,此处next记录的确实是下一个Entry
next = successor(e);
lastReturned = e;
//返回当前Entry
return e;
}
final Entry<K,V> prevEntry() {
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
next = predecessor(e);
lastReturned = e;
return e;
}
public void remove() {
if (lastReturned == null)
throw new IllegalStateException();
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
// deleted entries are replaced by their successors
if (lastReturned.left != null && lastReturned.right != null)
next = lastReturned;
deleteEntry(lastReturned);
expectedModCount = modCount;
lastReturned = null;
}
}
EntryIterator是TreeMap中继承自PrivateEntryIterator的类。
TreeMap中其他类型的Iterator类都继承自PrivateEntryIterator。
final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
EntryIterator(Entry<K,V> first) {
super(first);
}
public Map.Entry<K,V> next() {
return nextEntry();
}
}
TreeMap类中的successor方法:
主要作用是在调用iterator.next()方法时返回Entry<K,V>,移动next引用。
/**
* Returns the successor of the specified Entry, or null if no such.
*/
static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
if (t == null)
return null;
else if (t.right != null) {
Entry<K,V> p = t.right;
while (p.left != null)
p = p.left;
return p;
} else {
Entry<K,V> p = t.parent;
Entry<K,V> ch = t;
while (p != null && ch == p.right) {
ch = p;
p = p.parent;
}
return p;
}
}
从successor中可以看出iterator.next()返回的是当前的Entry。