初学Iterator迭代器设计模式

初学迭代器设计模式,一直不怎么理解,希望通过写篇博客加强理解。

我的理解是,迭代器设计模式可以解决这个问题。如果我有一个自已定义的类,这个类有当作容器的功能,比如里面有一个属性是Set,然后我想要遍历被放入这个容器类的一组ADT对象,而无需关注容器的具体类型,这时就可以使用迭代器设计模式了。

我们需要关注两个接口,Iterable和Iterator。这两个接口的大致结构如下:

public interface Iterable<T> {
	...
	Iterator<T> iterator();
}
public interface Iterator<E> {
	boolean hasNext();
	E next();
	void remove();
}

让自己的集合类实现Iterable接口,并实现自己独特的Iterator迭代器(hasNext,next,remove),允许客户端利用这个迭代器进行显示或隐式的迭代遍历:

for (E e : collection) {...}

Iterator<E> iter=collection.iterator();
while (iter.hasNext()) {...}

下面看一个具体的例子。比如我们要造一个停车场ParkingField,这是一个接口,它的实现类是ConcreteParkingField。然后车位的类叫Lot,停进去的东西有汽车,摩托车等,所以有一个接口Parkable。下面看看怎么实现迭代器。
我们首先需要给停车场这个容器提供遍历的功能,所以用ParkingField继承接口Iterable,再用ConcreteParkingField实现ParkingField。r然后需要提供一个迭代器,用ParkingIterator来实现接口Iterator。代码框架大致如下(里面的方法和属性不是重点,所以我把大部分的属性用…代替,重点是和迭代器相关的东西):

ParkingField继承接口Iterable

public interface ParkingField extends Iterable<String> {

	public static ParkingField create(int[] nos, int[] widths) throws Exception {
		return new ConcreteParkingField(nos, widths);
	}
	
	public static ParkingField create(Map<Integer, Integer> lots) throws Exception {
		return new ConcreteParkingField(lots);
	}
	
	public void parking(String type, String plate, int width, int num, String[] extraRegistrationInfo) throws Exception;

	public void parking(String type, String plate, int width, String[] extraRegistrationInfo);

	public double depart(String plate) throws Exception;
	
	public Map<Integer, String> status();
	
	public int getNumberOfLots();
	
	public boolean isLotInParkingField(int num, int width);
	
	public boolean isEmpty();

	int getLotWidth(int num) throws Exception;

}

ConcreteParkingField实现接口ParkingField

public class ConcreteParkingField implements ParkingField {
	private final ...
	private final Map<Lot, Parkable> status = new HashMap<>();
	private final ...
	
	public ConcreteParkingField(Map<Integer, Integer> lotsInfo) throws Exception {...}
	
	public ConcreteParkingField(int[] nos, int[] widths) {...}
	
	@Override
	public void parking(String type, String plate, int width, int num, String[] extraRegistrationInfo) throws Exception {...}
	
	@Override
	public void parking(String type, String plate, int width, String[] extraRegistrationInfo) {...}
	
	@Override
	public double depart(String plate) throws Exception {...}
	
	@Override
	public Map<Integer, String> status() {...}
	
	@Override
	public int getNumberOfLots() {...}
	
	@Override
	public boolean isLotInParkingField(int num, int width) {...}
	
	@Override
	public boolean isEmpty() {...}
	
	@Override
	public int getLotWidth(int num) throws Exception {...}
	
	@Override
	public String toString() {...}
	// 重点是这个。。。返回一个迭代器
	@Override
	public Iterator<String> iterator() {
		return new ParkingIterator(this.status);
	}

ParkingIterator来实现接口Iterator
注意,正常情况下Iterator的泛型应该是Parkable,为了不给ParkingField和client泄露Parkable,改成了String。

public class ParkingIterator implements Iterator<String> {

	private final ...
	private final ...
	private int count = 0;

	public ParkingIterator(...) {
		...
	}

	@Override
	public boolean hasNext() {
		return count < ....size();
	}

	@Override
	public String next() {
		...
		count ++;
		...
	}

	@Override
	public void remove() {
		...
	}

}

总的来说,迭代器模式让数据处理逻辑和内部数据管理分离,用一种更安全的方式进行遍历。此外,还可以还可以控制内部数据的顺序,这上面的例子中,于ParkingIterator的构造方法中加入一个排序即可。
以上,如有错误,恳请斧正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值