任何容器类,都可以通过某种方式插入、添加或者移除元素。例如:List 通过 add() 方法添加元素,get() 方法获取元素,remove() 方法移除元素。
但往更上层的角度思考,就好发现一个缺点:有时候我们希望针对 List 的方法,对于 Set 也可以生效,我们不需要关心容器的具体类型的前提下,对容器进行一些通用的操作。
迭代器由此应运而生,迭代器 Iterator 用来遍历并选择序列中的对象,它是一个轻量级对象,创建的代价也极小。
Iterator 主要有以下4类用途:
(1)容器类通过调用 iterator() 方法返回一个 Iterator 对象,Iterator 将准备好返回序列的第一个元素。
(2)Iterator 调用 next() 方法获取序列中的下一个元素。
(3)Iterator 调用 hashNext() 检查序列中是否还有元素。
(4)Iterator 使用 remove() 将迭代器最新的一个返回元素删除。
下面我们看看迭代器具体如何使用。
首先,定义一个工具类 Fruits 用来返回指定长度的集合。
public class Fruits {
public static String[] fruits = {"apple", "orange", "banana", "lemon", "watermelon", "cheery", "pear", "peach",
"strawberry", "mongo"};
public static class Fruit {
private int id;
private String name;
public Fruit(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Fruit{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
public static List<Fruit> arrayList(int size) {
if (size < 1) {
return new ArrayList();
}
if (size > fruits.length) {
size = fruits.length;
}
List<Fruit> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
Fruit fruit = new Fruit(i + 1, fruits[i]);
list.add(fruit);
}
return list;
}
}
接下来尝试调用迭代器内的各种方法,查看输出结果。
public class SimpleIteration {
public static void main(String[] args) {
ArrayList<Fruits.Fruit> fruitList = Fruits.arrayList(10);
Iterator<Fruits.Fruit> iterator = fruitList.iterator();
//判断迭代器是否还有元素
while (iterator.hasNext()){
//获取下一个元素
System.out.println(iterator.next());
}
//重新获取迭代器,移除前5个元素
System.out.println("开始移除元素");
iterator = fruitList.iterator();
for (int i = 0; i < 5; i++) {
iterator.next();
iterator.remove();
}
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
Fruit{id=1, name='apple'}
Fruit{id=2, name='orange'}
Fruit{id=3, name='banana'}
Fruit{id=4, name='lemon'}
Fruit{id=5, name='watermelon'}
Fruit{id=6, name='cheery'}
Fruit{id=7, name='pear'}
Fruit{id=8, name='peach'}
Fruit{id=9, name='strawberry'}
Fruit{id=10, name='mongo'}
开始移除元素
Fruit{id=6, name='cheery'}
Fruit{id=7, name='pear'}
Fruit{id=8, name='peach'}
Fruit{id=9, name='strawberry'}
Fruit{id=10, name='mongo'}
不过我们发现 Iterator 只支持元素的向前移动,但其还有一个功能更为强大的子类 ListIterator:
(1)容器类的 listIterator() 可以从指定起始位置后开始返回元素
(2)迭代器的 nextIndex() 获取后一个元素的索引
(3)迭代器的 previousIndex() 获取前一个元素的索引
(4)迭代器的 set() 可覆盖当前元素
public class SimpleIteration {
public static void main(String[] args) {
ArrayList<Fruits.Fruit> fruitList = Fruits.arrayList(10);
ListIterator<Fruits.Fruit> fruitListIterator = fruitList.listIterator(5);
//重新获取迭代器
while (fruitListIterator.hasNext()) {
System.out.print("\t" + fruitListIterator.previousIndex());
System.out.print("\t" + fruitListIterator.nextIndex());
System.out.print("\t" + fruitListIterator.next());
fruitListIterator.set(new Fruits.Fruit(0,"grape"));
System.out.println();
}
System.out.println(fruitList);
}
}
4 5 Fruit{id=6, name='cheery'}
5 6 Fruit{id=7, name='pear'}
6 7 Fruit{id=8, name='peach'}
7 8 Fruit{id=9, name='strawberry'}
8 9 Fruit{id=10, name='mongo'}
[Fruit{id=1, name='apple'}, Fruit{id=2, name='orange'}, Fruit{id=3, name='banana'}, Fruit{id=4, name='lemon'}, Fruit{id=5, name='watermelon'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}, Fruit{id=0, name='grape'}]
最后需要补充的是,foreach 也可以用于遍历各种集合类,只要是实现了 Iterable 接口的类,都可以用于 foreach 之中(foreach 支持遍历数组,但数组并未实现 Iterable 接口)。
public class SimpleIteration {
public static void main(String[] args) {
ArrayList<Fruits.Fruit> fruitList = Fruits.arrayList(10);
for (Fruits.Fruit fruit : fruitList) {
System.out.println(fruit);
}
}
}
Fruit{id=1, name='apple'}
Fruit{id=2, name='orange'}
Fruit{id=3, name='banana'}
Fruit{id=4, name='lemon'}
Fruit{id=5, name='watermelon'}
Fruit{id=6, name='cheery'}
Fruit{id=7, name='pear'}
Fruit{id=8, name='peach'}
Fruit{id=9, name='strawberry'}
Fruit{id=10, name='mongo'}
所有 Collection 类都默认实现了 Iterable 接口。
下面我们自己尝试实现一个 Iterable 接口,用于 foreach 循环。
public class IterableClass implements Iterable<String> {
protected String[] words = ("Do you know she has a brother ?").split(" ");
@Override
public Iterator<String> iterator() {
return new Iterator<String>() {
private int index = 0;
@Override
public boolean hasNext() {
return index < words.length;
}
@Override
public String next() {
return words[index++];
}
};
}
public static void main(String[] args) {
IterableClass iterableClass = new IterableClass();
for (String word : iterableClass) {
System.out.println(word);
}
}
}
Do
you
know
she
has
a
brother
?
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!