“这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战”
一、迭代器模式的概念和角色
(一)、迭代器模式的概念
迭代器模式又称为游标模式,迭代器模式提供一种顺序访问集合/容器对象元素的方法,而又无须暴露集合内部表示。迭代器模式可以为不同的容器提供一致的遍历行为,而不用关心容器内容元素组成结构,属于行为型模式。
迭代器模式的本质是抽离集合对象迭代行为到迭代器中,提供一致访问接口。
(二)、迭代器模式的角色
1、抽象迭代器(Itrtator):抽象迭代器复杂定义访问和遍历元素的接口
2、具体迭代器(ConcretrIterator):提供具体的元素遍历行为
3、抽象容器(Aggregate):复杂定义提供具体迭代器的接口
4、具体容器(ConcreteAggregate):创建具体迭代器
二、迭代器模式的应用场景
1、访问一个集合对象的内容而无需暴露它的内部表示
2、为遍历不同的集合结构提供一个统一的访问接口
三、迭代器模式的代码示例
Course:
public class Course {
private String name;
public Course(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
复制代码
Iterator:
public interface Iterator<E> {
E next();
boolean hasNext();
}
复制代码
CourseAggregate:
public interface CourseAggregate {
void add(Course courses);
void remove(Course courses);
Iterator<Course> iterator();
}
复制代码
IteratorImpl:
public class IteratorImpl<E> implements Iterator<E> {
private List<E> list;
private int cursor;
private E element;
public IteratorImpl(List list) {
this.list = list;
}
@Override
public E next() {
System.out.println("当前位置" + cursor + ":");
element = list.get(cursor);
cursor++;
return element;
}
@Override
public boolean hasNext() {
return cursor == list.size();
}
}
复制代码
CourseAggregateImpl:
public class CourseAggregateImpl implements CourseAggregate {
private List courseList;
public CourseAggregateImpl(List courseList) {
this.courseList = courseList;
}
@Override
public void add(Course course) {
courseList.add(course);
}
@Override
public void remove(Course course) {
courseList.remove(course);
}
@Override
public Iterator<Course> iterator() {
return new IteratorImpl<>(courseList);
}
}
复制代码
测试类:
public class Main {
public static void main(String[] args) {
Course java = new Course("Java");
Course python = new Course("Python");
Course js = new Course("JavaScript");
CourseAggregate courseAggregate = new CourseAggregateImpl(new ArrayList());
courseAggregate.add(java);
courseAggregate.add(python);
courseAggregate.add(js);
System.out.println("---课程列表---");
printCourse(courseAggregate);
courseAggregate.remove(js);
System.out.println("---删除操作后的课程列表---");
printCourse(courseAggregate);
}
private static void printCourse(CourseAggregate courseAggregate) {
Iterator<Course> iterator = courseAggregate.iterator();
while (!iterator.hasNext()) {
Course next = iterator.next();
System.out.println("《" + next.getName() + "》");
}
}
}
复制代码
四、迭代器模式在源码中的应用
在Iterator的源码中,同样定义了hasNext(),以及next()方法。
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());
}
}
复制代码
在ArrayList中有一个内部类Itr,实现了Iterator接口,该类中对hasNext()以及next()方法进行了实现
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
// ......省略中间代码
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
Itr() {
}
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
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];
}
// ......省略中间代码
}
// ......省略中间代码
}
复制代码
五、迭代器模式的优缺点
(一)、优点
1、多态迭代:为不同的聚合结构提供一致的遍历接口,即一个迭代接口可以访问不同的结合对象
2、简化集合对象接口:迭代器模式将集合对象本身应该提供的元素迭代接口抽取到了迭代器中,使结合对象无须关心具体的迭代行为
3、元素迭代功能多样化:每个结合对象都可以提供一个或多个不同的迭代器,使得同种元素聚合结构可以有不同的迭代行为
4、解耦迭代与结合:迭代器模式封装了具体的迭代算法,迭代算法的变化,不会影响到集合对象的架构
(二)、缺点
1、对于比较简单的遍历,使用迭代器方式比较繁琐