迭代器模式,遍历用,类似 Java 的 Iterator 接口,提供一种判断是否有下一个和取出下一个的方法。由于 Java 的集合基本已经实现了 Iterator,所以一般不需要自己手动实现。
组合模式,比如 Android 的 View 树就是这东西。对于组合的迭代遍历,比如下面这样
组合模式.png每个节点内部有个栈,存储迭代器列表,比如 ViewGroup 内部先是自己的迭代器,next 就读到了 ViewGroupA,判断 ViewGroupA 是个组合的话那就把它的迭代器再放到自己的栈里,这样 ViewGroup 再 next 读取的就是 ViewGroupA1,当 hasNext 时判断这迭代器没有 next 了,就是读完 ViewGroupA3 后,就从栈顶移除,再次主动调用一次 hasNext,就又读到栈底原来 ViewGroup 的迭代器了,这样就取得 ViewGroupB 的迭代器。这是深度优先遍历的迭代。
// 自定义的适用于组合的迭代器
public class CompositeIterator implements Iterator {
Stack stack = new Stack();
// 传进来一个根节点获取的迭代器
public CompositeIterator(Iterator iterator) {
stack.push(iterator);
}
public Object next() {
if (hasNext()) {
Iterator iterator = (Iterator) stack.peek();
View viewComponent = (Component)iterator.next();
if (viewComponent instanceOf ViewGroup) {
stack.push(viewComponent.createIterator());
}
return viewComponent;
} else {
return null;
}
}
public boolean hasNext() {
if (stack.empty()) {
return false;
} else {
Iterator iterator = (Iterator) stack.peek();
if (!iterator.hasNext()) {
stack.pop();
return hasNext();
} else {
return true;
}
}
}
}
如果要广度优先,应该是将栈改成队列,每次 next 都从第一层迭代器取,遇到 ViewGroup 后迭代器往队列添加,这样第一层取完后删掉就能读到 ViewGroupA 的迭代器了。
网友评论