一、引言
迭代器是设计模式的一种,迭代器模式提供方法来访问容器中的的元素,这听起来跟c语言中指针十分相似,其实数组访问中的指针本质上就是迭代器的一种。Iterrator对象就是迭代器,而iterator() 是 Java 集合框架中的一个方法,它返回一个 Iterator 对象,该对象可以用来遍历集合中的元素。
二、迭代器
2.1 迭代器对象的创建
在讲如何创建迭代器对象之前首先需要了解的是迭代器的种类,这里引用一下FASTR博主中的类结构图来说明
通过底层代码的查看我们可以发现在Iterable接口中有一个Iterator方法,它返回一个Iterator对象。
public interface Iterable<T> {
/**
* Returns an iterator over elements of type {@code T}.
*
* @return an Iterator.
*/
Iterator<T> iterator();
而Iterator对象中则是拥有三个方法
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
返回值类型 | 方法名 | 功能 |
---|---|---|
boolean | hasNext() | 判断集合是否还有元素,如果返回 true 表示集合还有元素,返回 false 表示集合中没有元素 |
E | next() | 获取集合中的下一个元素,通常搭配hasNext()来使用,判断出存在元素再使用该方法获取下一个元素 |
void | remove() | 删除集合中的元素。 |
在了解了类结构图之后我们就可以使用iterator()方法来创建对应的迭代器对象。
2.2 迭代器的使用
我们先来看一下最常见的ArrayList集合的迭代器使用案例
package pojo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
int value = iterator.next();
System.out.print(value + " ");
}
}
}
运行结果为:
在该案例中,首先hasNext()方法的指针先指向1,确定存在该元素后打印,然后是2,3。在3之后由于没有下一个元素就会跳出while循环。
上述案例演示了hasNext和next方法的基本使用,那么remove()其实在迭代器中的使用也十分简单
package pojo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()) {
int value = iterator.next();
if(value == 1) iterator.remove();
}
System.out.println("删除后" + list);
}
}
运行结果为:元素1被删除
那么Iterator的子类ListIterator有什么特殊之处呢。它允许程序员在列表(如 ArrayList、LinkedList 等)中双向遍历,同时支持元素的添加和删除操作。我们可以看一下底层代码中对几个新方法的描述
/**
* Returns {@code true} if this list iterator has more elements when
* traversing the list in the reverse direction. (In other words,
* returns {@code true} if {@link #previous} would return an element
* rather than throwing an exception.)
*
* @return {@code true} if the list iterator has more elements when
* traversing the list in the reverse direction
*/
boolean hasPrevious();
/**
* Returns the previous element in the list and moves the cursor
* position backwards. This method may be called repeatedly to
* iterate through the list backwards, or intermixed with calls to
* {@link #next} to go back and forth. (Note that alternating calls
* to {@code next} and {@code previous} will return the same
* element repeatedly.)
*
* @return the previous element in the list
* @throws NoSuchElementException if the iteration has no previous
* element
*/
E previous();
/**
* Returns the index of the element that would be returned by a
* subsequent call to {@link #next}. (Returns list size if the list
* iterator is at the end of the list.)
*
* @return the index of the element that would be returned by a
* subsequent call to {@code next}, or list size if the list
* iterator is at the end of the list
*/
int nextIndex();
/**
* Returns the index of the element that would be returned by a
* subsequent call to {@link #previous}. (Returns -1 if the list
* iterator is at the beginning of the list.)
*
* @return the index of the element that would be returned by a
* subsequent call to {@code previous}, or -1 if the list
* iterator is at the beginning of the list
*/
int previousIndex();
/**
* Replaces the last element returned by {@link #next} or
* {@link #previous} with the specified element (optional operation).
* This call can be made only if neither {@link #remove} nor {@link
* #add} have been called after the last call to {@code next} or
* {@code previous}.
*
* @param e the element with which to replace the last element returned by
* {@code next} or {@code previous}
* @throws UnsupportedOperationException if the {@code set} operation
* is not supported by this list iterator
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this list
* @throws IllegalArgumentException if some aspect of the specified
* element prevents it from being added to this list
* @throws IllegalStateException if neither {@code next} nor
* {@code previous} have been called, or {@code remove} or
* {@code add} have been called after the last call to
* {@code next} or {@code previous}
*/
void set(E e);
/**
* Inserts the specified element into the list (optional operation).
* The element is inserted immediately before the element that
* would be returned by {@link #next}, if any, and after the element
* that would be returned by {@link #previous}, if any. (If the
* list contains no elements, the new element becomes the sole element
* on the list.) The new element is inserted before the implicit
* cursor: a subsequent call to {@code next} would be unaffected, and a
* subsequent call to {@code previous} would return the new element.
* (This call increases by one the value that would be returned by a
* call to {@code nextIndex} or {@code previousIndex}.)
*
* @param e the element to insert
* @throws UnsupportedOperationException if the {@code add} method is
* not supported by this list iterator
* @throws ClassCastException if the class of the specified element
* prevents it from being added to this list
* @throws IllegalArgumentException if some aspect of this element
* prevents it from being added to this list
*/
void add(E e);
E previous() 返回列表中的前一个元素,并将迭代器位置向后移动一个位置。
int nextIndex() 返回对 next 的后续调用将返回的元素的索引(在正向遍历列表中时)。
int previousIndex() 返回对 previous 的后续调用将返回的元素的索引(在反向遍历列表中时)。
void set(E e) 用指定的元素替换上次 next 或 previous 访问的元素(可选操作)。
void add(E e) 将指定的元素插入列表(可选操作)。该元素将插入到 next 或 previous 最后一次访问的位置。