感谢Java软件结构与数据结构 John Lewis Joseph chase 著 金名译
干大事而惜身,见小利而忘命,非英雄也!
1.迭代器定义
迭代器是一个对象,允许用户每次获得和使用集合中的一个元素,它与某个集合一同使用,但是它是一个单独的对象。迭代器是有助于实现某个集合的一种机制。
在java中,迭代器提供了一种标准方法,可以一次访问集合中的每一个元素,这是一种通用的操作。迭代器是一个对象,允许用户每次获取和使用集合中的一个元素。JavaAPI中迭代器由两个基本的接口实现的:
- Iterator:用于定义一个对象,该对象作为一个迭代器。
- Iterable:用于定义一个集合,从该集合中可以抽取出一个迭代器。
集合定义为Iterable,当需要的时候可以提供一个Iterator对象。Iterable接口只有一个方法,名字为 iterator() 返回值是一个Iterator对象,当创建一个集合时需要确定元素的类型,通常是在迭代器中定义元素:
public Iterator<T> iterator() {
return new ArrayListIterator();
}
Iterator接口含有3个方法。前两个是hasNext和next,可以用于依次访问集合中的元素。
大多数的迭代器都是fail-fast的,当迭代器使用之中,如果要修改集合将抛出一个异常。
许多时候我们含显示迭代器的while,而不是使用for-each循环。因为,首先是一般不需要迭代的所有元素,另外,如果使用remove,需要调用显示的迭代器,然而foreach没有提供对迭代器的显示访问。
2.迭代器关键补充概念
【1】迭代器是一个对象,提供了一种依次访问集合中的每个元素的方式。
【2】经常把集合定义为Iterable的,这意味着需要时可以提供一个迭代器。
【3】迭代器的可选方法remove使得它可以删除一个元素,,而无需在遍历集合。
【4】大多是的迭代器都是fail-fast的,当迭代器仍在使用时,如果修改集合将抛出一个异常。
【5】不能假设迭代器访问元素的顺序,除非显示声明了。
【6】迭代器类往往实现为它所属的集合的内部类。
【7】迭代器检查修改计数,以确保与集合的修改计数一致。
3. 迭代器的实现
2.1 数组实现的迭代器
private class ArrayListIterator implements Iterator<T>
{
int iteratorModCount;
int current;
/**
* Sets up this iterator using the specified modCount.
*
* @param modCount the current modification count for the ArrayList
*/
public ArrayListIterator()
{
iteratorModCount = modCount;
current = 0;
}
/**
* Returns true if this iterator has at least one more element
* to deliver in the iteration.
*
* @return true if this iterator has at least one more element to deliver
* in the iteration
* @throws ConcurrentModificationException if the collection has changed
* while the iterator is in use
*/
public boolean hasNext() throws ConcurrentModificationException
{
if (iteratorModCount != modCount)
throw new ConcurrentModificationException();
return (current < rear);
}
/**
* Returns the next element in the iteration. If there are no
* more elements in this iteration, a NoSuchElementException is
* thrown.
*
* @return the next element in the iteration
* @throws NoSuchElementException if an element not found exception occurs
* @throws ConcurrentModificationException if the collection has changed
*/
public T next() throws ConcurrentModificationException
{
if (!hasNext())
throw new NoSuchElementException();
current++;
return list[current - 1];
}
/**
* The remove operation is not supported in this collection.
*
* @throws UnsupportedOperationException if the remove method is called
*/
public void remove() throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
}
2.2 链表实现的迭代器
/**
* LinkedIterator represents an iterator for a linked list of linear nodes.
*/
private class LinkedListIterator implements Iterator<T>
{
private int iteratorModCount; // the number of elements in the collection
private LinearNode<T> current; // the current position
/**
* Sets up this iterator using the specified items.
*
* @param collection the collection the iterator will move over
* @param size the integer size of the collection
*/
public LinkedListIterator()
{
current = head;
iteratorModCount = modCount;
}
/**
* Returns true if this iterator has at least one more element
* to deliver in the iteration.
*
* @return true if this iterator has at least one more element to deliver
* in the iteration
* @throws ConcurrentModificationException if the collection has changed
* while the iterator is in use
*/
public boolean hasNext() throws ConcurrentModificationException
{
if (iteratorModCount != modCount)
throw new ConcurrentModificationException();
return (current != null);
}
/**
* Returns the next element in the iteration. If there are no
* more elements in this iteration, a NoSuchElementException is
* thrown.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iterator is empty
*/
public T next() throws ConcurrentModificationException
{
if (!hasNext())
throw new NoSuchElementException();
T result = current.getElement();
current = current.getNext();
return result;
}
/**
* The remove operation is not supported.
*
* @throws UnsupportedOperationException if the remove operation is called
*/
public void remove() throws UnsupportedOperationException
{
throw new UnsupportedOperationException();
}
}