概念 :
迭代器模式是一种行为型设计模式,它提供了一种访问集合对象元素的方法,而无需暴露其内部表示。通过使用迭代器,可以按照特定顺序遍历集合中的元素。
特点 :
- 将遍历和具体集合分离,使得能够独立地改变集合的实现方式。
- 提供了一个统一的接口来访问不同类型的集合对象。
- 隐藏了对于底层数据结构和算法的细节。
优点 :
- 简化了客户端代码,将遍历逻辑从业务逻辑中解耦出来。
- 提供了对不同类型集合对象进行统一操作的能力。
- 支持多种遍历方式。
缺点 :
- 对于某些复杂数据结构或算法可能需要自定义迭代器实现,增加了开发成本和复杂性。
- 在某些情况下可能会导致额外内存消耗。
适用场景 :
- 当需要以相同方式遍历不同类型(如数组、链表、树等)的集合对象时可以使用迭代器模式。
- 当希望隐藏底层数据结构并提供一个统一接口来访问元素时可以使用迭代器模式。
实现方式 :
内部迭代器:
在集合对象内部定义一个迭代器类,由集合对象主动调用迭代器的方法进行遍历。
实现原理:
- 集合类中包含一个迭代器类并实现含获取迭代器的方法。
- 迭代器类实现一个接口或抽象类,其中包含判断是否有下一个元素和获取下一个元素的方法。
- 在具体集合类中定义一个私有内部类作为具体的迭代器实现,并在该内部类中实现相关方法。
实现代码:
java
// 这里假设我们有一个名为MyCollection的具体集合类
import java.util.ArrayList;
import java.util.List;
class MyCollection<T> {
private List<T> elements;
public MyCollection() {
this.elements = new ArrayList<>();
}
public void add(T element) {
elements.add(element);
}
// 获取内部迭代器
public Iterator<T> getIterator() {
return new ConcreteIterator();
}
// 具体迭代器类,实现了Iterator接口
private class ConcreteIterator implements Iterator<T> {
private int index;
@Override
public boolean hasNext() {
return index < elements.size();
}
@Override
public T next() {
if (this.hasNext()) {
return elements.get(index++);
}
return null;
}
}
}
// 定义一个迭代器接口
interface Iterator<T> {
boolean hasNext();
T next();
}
public class Main {
public static void main(String[] args) {
// 使用示例
MyCollection<String> collection = new MyCollection<>();
collection.add("A");
collection.add("B");
collection.add("C");
// 获取内部迭代器并遍历集合元素
Iterator<String> iterator = collection.getIterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
在上述示例中,我们创建了一个具体集合类 MyCollection ,其中包含一个私有内部类 ConcreteIterator 实现了迭代器接口。
在具体集合类中定义的 getIterator() 方法返回该内部迭代器对象。客户端代码可以通过调用该方法获取到具体集合的内部迭代器,并使用循环遍历输出每个元素。在实际应用中,还可以根据需要对内部迭代器进行扩展,例如添加过滤条件、排序等操作。
存在的问题:
- 内部迭代器无法同时处理多个不同类型的集合对象。
- 内部迭代器无法灵活地改变遍历顺序或跳过特定元素。
- 集合对象对于每个元素都要进行完整遍历操作,如果只需要访问某些特定元素可能会造成性能损失。
外部迭代器:
客户端代码通过调用外部的迭代器来遍历集合对象。在外部迭代器中,客户端代码通过手动调用迭代器的方法来遍历集合对象,并可以灵活地控制遍历顺序和跳过特定元素。
实现原理:
- 在具体集合类中提供一个返回该迭代器对象的方法。
- 迭代器可以是自己创建的也可以使用java内置的迭代器。
- 在客户端代码中手动调用迭代器的方法进行遍历操作。
实现代码:
java
// 这里假设我们有一个名为MyCollection的具体集合类
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
class MyCollection<T> {
private List<T> elements;
public MyCollection() {
this.elements = new ArrayList<>();
}
public void add(T element) {
elements.add(element);
}
// 获取内部迭代器
public Iterator<T> getIterator() {
return elements.iterator();
}
}
public class Main {
public static void main(String[] args) {
// 使用示例
MyCollection<String> collection = new MyCollection<>();
collection.add("A");
collection.add("B");
collection.add("C");
// 获取外部迭代器并遍历集合元素
Iterator<String> iterator = collection.getIterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
在上述示例中,我们创建了一个具体集合类 MyCollection ,其中的 getIterator() 方法返回了Java内置的迭代器对象。
在客户端代码中,我们通过调用具体集合的 getIterator() 方法获取到外部迭代器,并使用循环遍历输出每个元素。在实际应用中,可以根据需要使用不同类型的外部迭代器,例如自定义实现一个针对特定需求进行封装的外部迭代器类。这样可以灵活地控制遍历逻辑和提供额外功能。