(一)迭代器的介绍
- 迭代器存在的意义:
使用容器,必须对容器的确切类型进行编程。若遇到这种情况:原本是对List进行编码的,但是后来发现能够把相同的代码应用于Set,将会非常方便。此时问题就是如何不重写代码就可以应用于不同类型的容器。—使用迭代器就可以达到这个目的。 - 迭代器是一个对象,它的原理是工作并选择序列中的对象,而客户端程序员不必知道或关心该序列底层的结构。
- 迭代器通常被称为轻量级对象,创建它的代价小。
(二)Iterator
Iterator只能单向移动:
- 使用iterator()要求容器返回一个Iterator。Iterator将准备好返回序列的第一个元素。
- 使用next()获得序列中的下一个元素。
- 使用hasNext()判断序列中是否还有元素。
- 使用remove()将迭代器新近返回的元素删除。
举例1:
Iterator中方法的使用
package www.fanfan.com;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class Fruit1{
private String type;
public Fruit1(String type){
this.type = type;
}
public String toString(){
return this.type;
}
}
public class SimpleIterator {
public static void main(String[] args) {
List<Fruit1> fruit1 = new ArrayList<Fruit1>();
// 使用add()方法顺序添加元素并打印
fruit1.add(new Fruit1("Apple"));
fruit1.add(new Fruit1("Orange"));
fruit1.add(new Fruit1("Fuji"));
fruit1.add(new Fruit1("Pitch"));
fruit1.add(new Fruit1("Gala"));
System.out.println("1:"+fruit1);
//1.1 判断序列是否为空
//1.2 每次返回序列中的下一个元素
Iterator<Fruit1> it = (Iterator<Fruit1>) fruit1.iterator();
while (it.hasNext()){
Fruit1 f = it.next();
System.out.print(f+" ");
}
System.out.println();
//2.1 返回序列中的下一个元素
//2.2 将最新返回的元素删除
it = fruit1.iterator();
for (int i = 0; i < 2; i++){
it.next();
it.remove();
}
System.out.println(fruit1);
}
}
注意:
(1)使用iterator()方法获得的是当前序列(即当前fruit1的序列),不会再随着fruit1的改变再改变。
(2)使用next()方法之后会获得序列中的下一个元素,当多次使用next()方法之后,想要在一个新的方法中(或新的位置处)重新获得序列的第一个元素,需要使用iterator()方法重新定义;
(3)要想删除元素,首先就应该获得这个元素,因此next()方法与remove()方法一起使用。
Iterator可以接受容器并传递它,从而在每个对象上都执行操作,这种思想十分强大。
举例2:
display()方法不包含任何有关它所遍历的序列的类型的信息,这展示出了Iterator的作用:能够将遍历序列的操作与序列底层的结构分离。
import java.util.*;
class Fruit{
private String type;
public Fruit(String type){
this.type = type;
}
public String toString(){
return this.type;
}
}
public class CrossContainerIteration {
public static void display(Iterator<Fruit> it){
while (it.hasNext()){
System.out.print(it.next()+" ");
}
System.out.println();
}
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Apple"));
fruits.add(new Fruit("Orange"));
fruits.add(new Fruit("Fuji"));
fruits.add(new Fruit("Pitch"));
fruits.add(new Fruit("Gala"));
LinkedList<Fruit> fruitsLL = new LinkedList<Fruit>(fruits);
HashSet<Fruit> fruitsHS = new HashSet<Fruit>(fruits);
display(fruits.iterator());
display(fruitsLL.iterator());
display(fruitsHS.iterator());
}
}
(三)ListIterator
- ListIterator是一个更加强大的Iterator的子类型,它只能用于各种List类的访问。
- ListIterator可以双向访问。
- 可以产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引。
- 可以使用set()方法替换它访问过的最后一个元素。
- 可以调用listIterator()方法产生一个指向List开始处的ListIterator。
- 可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。
举例3:
ListIterator的方法使用:
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
class Fruit1{
private String type;
public Fruit1(String type){
this.type = type;
}
public String toString(){
return this.type;
}
}
public class ListIteratorTest {
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Apple"));
fruits.add(new Fruit("Orange"));
fruits.add(new Fruit("Fuji"));
fruits.add(new Fruit("Pitch"));
fruits.add(new Fruit("Gala"));
ListIterator<Fruit> it = fruits.listIterator();
//判断序列中是否还有元素,打印出元素,并且打印出当前位置的前一个和后一个元素的索引
//遍历结束之后it就指向了序列的最后
while (it.hasNext()){
System.out.print(it.next()+" "+it.nextIndex()+" "+it.previousIndex()+";");
}
System.out.println();
//ListIterator可以双向移动,现在让it指向序列的第一个元素
while (it.hasPrevious()){
System.out.print(it.previous()+" ");
}
System.out.println();
//使用listIterator(n)方法创建一个一开始就指向列表索引为n的序列
it = fruits.listIterator(2);
while (it.hasNext()){
it.next();
it.set(new Fruit("Gala"));
}
System.out.println(fruits);
}
}
使用Iterator 和 ListIterator获得的序列的修改会影响原序列;但是一旦使用 iterator()或 listIterator()方法获取了序列,原序列的修改就不会影响新的序列。