设计模式-迭代器模式
# 设计模式-迭代器模式
# 概述
现在我们假设电视频道是存储于电视机的,而当我们切换频道的时候,并非是去控制电视机,而是通过遥控器去遍历频道。我们让电视机只负责存储电视频道,而遥控器只负责遍历电视频道。
# 定义
迭代器用于对一个聚合对象进行遍历,通过引入迭代器可以将数据的遍历功能从聚合对象中分离出来,聚合对象只负责存储数据,而遍历数据由迭代器来完成,简化了聚合对象的设计。
迭代器模式: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不用暴露该对象的内部表示。
# 迭代器模式结构
迭代器模式包含以下4个角色:
- 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
- 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
- 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
- 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。
# 迭代器模式应用案例
1、创建迭代器接口
public interface Iterator {
boolean hasNext();
Object next();
}
2、创建容器接口
public interface Container {
Iterator getIterator();
}
3、创建一个聚合对象容器
public class NameRepository implements Container {
public String[] names = {"Robert", "John", "Julie", "Lora"};
@Override
public Iterator getIterator() {
return new NameIterator();
}
private class NameIterator implements Iterator {
int index;
@Override
public boolean hasNext() {
return index < names.length;
}
@Override
public Object next() {
if (this.hasNext()) {
return names[index++];
}
return null;
}
}
}
4、案例实现
public class IteratorPatternDemo {
public static void main(String[] args) {
NameRepository nameRepository = new NameRepository();
for(Iterator iter = nameRepository.getIterator(); iter.hasNext();){
String name = (String)iter.next();
System.out.println("Name : " + name);
}
}
}
# 迭代器优缺点
优点:
- 迭代器模式支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。
- 迭代器模式简化了聚合类,在原有的聚合对象中不需要再提供数据遍历等方法。
- 迭代器模式中由于引入了抽象层,增加新的聚合类和迭代器类都能方便。
缺点:
- 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
- 抽象迭代器的设计难度较大,需要充分考虑到系统将来的扩展。
# 迭代器适用环境
- 访问一个聚合对象的内容而无须暴露它的内部表示。将聚合对象的访问与内部数据的存储分离,使得访问聚合对象无须了解其内部的实现细节。
- 需要为一个聚合对象提供多种遍历方式。
- 为遍历不同的聚合结构提供一个统一的接口,在该接口的实现类中为不同的聚合结构提供不同的遍历方式,而客户端可以一致性操作该接口。
# Java内置的迭代器
Collection接口中:
/**
* Returns an iterator over the elements in this collection. There are no
* guarantees concerning the order in which the elements are returned
* (unless this collection is an instance of some class that provides a
* guarantee).
*
* @return an <tt>Iterator</tt> over the elements in this collection
*/
Iterator<E> iterator();
迭代器接口:
public interface Iterator<E> {
/**
* Returns {@code true} if the iteration has more elements.
* (In other words, returns {@code true} if {@link #next} would
* return an element rather than throwing an exception.)
*
* @return {@code true} if the iteration has more elements
*/
boolean hasNext();
/**
* Returns the next element in the iteration.
*
* @return the next element in the iteration
* @throws NoSuchElementException if the iteration has no more elements
*/
E next();
/**
* Removes from the underlying collection the last element returned
* by this iterator (optional operation). This method can be called
* only once per call to {@link #next}. The behavior of an iterator
* is unspecified if the underlying collection is modified while the
* iteration is in progress in any way other than by calling this
* method.
*
* @implSpec
* The default implementation throws an instance of
* {@link UnsupportedOperationException} and performs no other action.
*
* @throws UnsupportedOperationException if the {@code remove}
* operation is not supported by this iterator
*
* @throws IllegalStateException if the {@code next} method has not
* yet been called, or the {@code remove} method has already
* been called after the last call to the {@code next}
* method
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* Performs the given action for each remaining element until all elements
* have been processed or the action throws an exception. Actions are
* performed in the order of iteration, if that order is specified.
* Exceptions thrown by the action are relayed to the caller.
*
* @implSpec
* <p>The default implementation behaves as if:
* <pre>{@code
* while (hasNext())
* action.accept(next());
* }</pre>
*
* @param action The action to be performed for each element
* @throws NullPointerException if the specified action is null
* @since 1.8
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
迭代器基本使用:
public class JavaIteratorDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(8);
list.add(2);
list.add(6);
list.add(7);
list.add(10);
Iterator<Integer> it = list.iterator();
while (it.hasNext()) {
Integer i = it.next();
if (i < 10) {
it.remove(); // 删除小于 10 的元素
}
}
System.out.println(list);
}
}
# 参考
Java设计模式
上次更新: 2024/06/29, 15:13:44