一、前言
二、Iterator接口
Iterator 通常被称为轻量级对象,因为创建它的开销比较小.可以通过调用容器的 iterator()方法来获取它的Iterator.
下面是Iterator接口定义:
代码清单-1
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
下面来看一个使用示例:
代码清单-2
public class IteratorExample {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("aaa");
a.add("bbb");
a.add("ccc");
System.out.println("Before iterate : " + a);
Iterator<String> it = a.iterator();
while (it.hasNext()) {
String t = it.next();
if ("bbb".equals(t)) {
it.remove();
}
}
System.out.println("After iterate : " + a);
}
}
输出结果如下:
Before iterate : [aaa, bbb, ccc]
After iterate : [aaa, ccc]
注意:Iterator.remove()是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为.而且每调用一次next()方法,remove()方法只能被调用一次,如果违反这个规则将抛出一个异常.
三、ListIterator接口
ListIterator是一个功能更加强大的迭代器, 它只能用于各种List类型的访问。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator.
ListIterator接口定义如下:
代码清单-3public interface ListIterator<E> extends Iterator<E> {
boolean hasNext();
E next();
boolean hasPrevious();
E previous();
int nextIndex();
int previousIndex();
void remove();
void set(E e);
void add(E e);
}
由以上定义我们可以推出ListIterator可以:
(1)双向移动.
(2)产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引.
(3)可以使用set()方法替换它访问过的最后一个元素.
(4)可以使用add()方法在next()方法返回的元素之前或previous()方法返回的元素之后插入一个元素.
下面就简单演示所有这些功能:
代码清单-4
public class ListIteratorExample {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<String>();
a.add("aaa");
a.add("bbb");
a.add("ccc");
System.out.println("Before iterate : " + a);
ListIterator<String> it = a.listIterator();
while (it.hasNext()) {
System.out.println(it.next() + ", " + it.previousIndex() + ", " + it.nextIndex());
}
while (it.hasPrevious()) {
System.out.print(it.previous() + " ");
}
System.out.println();
it = a.listIterator(1);
while (it.hasNext()) {
String t = it.next();
if ("ccc".equals(t)) {
it.set("nnn");
} else {
it.add("kkk");
}
}
System.out.println("After iterate : " + a);
}
}
输出结果如下:
Before iterate : [aaa, bbb, ccc]
aaa, 0, 1
bbb, 1, 2
ccc, 2, 3
ccc bbb aaa
After iterate : [aaa, bbb, kkk, nnn]
四、Iterator使用场景
在以下情况下可以使用Iterator接口代替for-each结构:
(1)删除当前的元素.for-each结构隐藏了迭代器, 所以你不能调用remove()方法. 因此for-each结构无法用于过滤.
(2)并行地迭代多个集合.
下面的代码片段展示了如何使用一个迭代器来过滤任意一个集合——即遍历这个集合并删除指定元素.
代码清单-5
static void filter(Collection<?> c) {
for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}
以上代码是多态的, 意味着它对任何集合都起作用, 而不用去考虑具体的实现.可见使用Java集合框架来编写多态的算法是多么的简单.
五、参考资料
http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html
《Thinking In Java》
来源:oschina
链接:https://my.oschina.net/u/941605/blog/220134