赞
踩
迭代器模式 (Iterator Pattern) 是一种行为型设计模式,它提供一种顺序访问聚合对象(如列表、集合等)中的元素,而无需暴露聚合对象的内部表示。迭代器模式将遍历逻辑封装在一个迭代器对象中,使得我们可以使用统一的方式遍历不同类型的聚合对象,同时也可以简化客户端代码。
迭代器模式主要包含以下角色:
hasNext()
、next()
等方法。【例】定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现,其类图如下:
具体实现代码如下:
Student.java
public class Student { private String name; private String number; public Student() { } public Student(String name, String number) { this.name = name; this.number = number; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", number='" + number + '\'' + '}'; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } }
StudentIterator.java
//抽象迭代器角色接口
public interface StudentIterator {
//判断是否还有元素
boolean hasNext();
//获取下一个元素
Student next();
}
StudentIteratorImpl.java
//具体迭代器角色类 public class StudentIteratorImpl implements StudentIterator{ private List<Student> list; //用来记录遍历时的位置 private int position = 0; public StudentIteratorImpl(List<Student> list) { this.list = list; } @Override public boolean hasNext() { return position < list.size(); } @Override public Student next() { //从集合中或者去指定位置的元素 Student currentStudent = list.get(position); position++; return currentStudent; } }
StudentAggregate.java
//抽象聚合(容器)角色接口
public interface StudentAggregate {
//添加学生
void addStudent(Student stu);
//删除学生
void removeStudent(Student stu);
//获取迭代器对象
StudentIterator getStudentIterator();
}
StudentAggregateImpl.java
public class StudentAggregateImpl implements StudentAggregate{ private List<Student> list = new ArrayList<>(); @Override public void addStudent(Student stu) { list.add(stu); } @Override public void removeStudent(Student stu) { list.remove(stu); } //获取迭代器对象 @Override public StudentIterator getStudentIterator() { return new StudentIteratorImpl(list); } }
Client.java
public class Client { public static void main(String[] args) { //创建聚合(容器)对象 StudentAggregateImpl aggregate = new StudentAggregateImpl(); Student student1 = new Student("Tom", "1001"); Student student2 = new Student("Mike", "1002"); Student student3 = new Student("Jerry", "1003"); Student student4 = new Student("Mary", "1004"); //添加元素 aggregate.addStudent(student1); aggregate.addStudent(student2); aggregate.addStudent(student3); aggregate.addStudent(student4); //删除元素 aggregate.removeStudent(student3); //遍历聚合对象 // 1.获取迭代器对象 StudentIterator iterator = aggregate.getStudentIterator(); // 2.遍历 while (iterator.hasNext()){ // 3.获取元素 Student student = iterator.next(); System.out.println(student.toString()); } } }
结果如下:
Student{name='Tom', number='1001'}
Student{name='Mike', number='1002'}
Student{name='Mary', number='1004'}
(1)迭代器模式的优缺点如下:
(2)总体来说,迭代器模式适用于需要统一遍历接口、封装遍历逻辑、解耦聚合对象与遍历操作的场景。它可以提供更加灵活、通用和可维护的遍历操作,但在某些情况下,可能会增加代码的复杂性。因此,在使用迭代器模式时需要综合考虑具体的设计需求和项目情况。
(1)迭代器模式通常适用于以下场景:
(2)迭代器模式在现实生活中的应用也非常广泛,例如集合类、数据库查询结果等都可以使用迭代器模式来统一遍历操作接口。
(1)迭代器模式在 Java 的很多集合类中被广泛应用,接下来看下面的例子:
public class TestArratList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//添加元素
list.add("1001");
list.add("1002");
list.add("1003");
//删除元素
list.remove("1003");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
结果如下:
1001
1002
(2)看完这段代码是不是觉得很熟悉,它与我们上面的代码基本类似。单列集合都使用到了迭代器,所以现在以 ArrayList
举例来说明:
List
:抽象聚合类;ArrayList
:具体的聚合类;Iterator
:抽象迭代器;list.iterator()
:返回的是实现了 Iterator 接口的具体迭代器对象;(3)具体来看看 ArrayList 的部分关键代码实现:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // 下一个要返回元素的索引 int lastRet = -1; // 上一个返回元素的索引 int expectedModCount = modCount; Itr() {} //判断是否还有元素 public boolean hasNext() { return cursor != size; } //获取下一个元素 public E next() { checkForComodification(); int i = cursor; if (i >= size) throw new NoSuchElementException(); Object[] elementData = ArrayList.this.elementData; if (i >= elementData.length) throw new ConcurrentModificationException(); cursor = i + 1; return (E) elementData[lastRet = i]; } //删除当前元素 public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { ArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; expectedModCount = modCount; } catch (IndexOutOfBoundsException ex) { throw new ConcurrentModificationException(); } } //... }
(4)这部分代码大致就是在 iterator 方法中返回了一个实例化的 Iterator
对象。Itr
是一个内部类,它实现了 Iterator 接口并重写了其中的抽象方法。此外,通过下图可知 ArrayList 与 Iterable 的关系:
package java.lang; import java.util.Iterator; import java.util.Objects; import java.util.Spliterator; import java.util.Spliterators; import java.util.function.Consumer; public interface Iterable<T> { Iterator<T> iterator(); default void forEach(Consumer<? super T> action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } default Spliterator<T> spliterator() { return Spliterators.spliteratorUnknownSize(iterator(), 0); } }
(5)当我们在使用 Java 开发的时想使用迭代器模式的话,只要让我们自己定义的容器类实现 java.util.Iterable
并实现其中的 iterator()
方法使其返回一个 java.util.Iterator
的实现类就可以了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。