Java 复合模式的递归迭代器
我有树类AbstractComponent、Leaf和Composite:Java 复合模式的递归迭代器,java,iterator,composite,Java,Iterator,Composite,我有树类AbstractComponent、Leaf和Composite: public abstract class AbstractComponent { privavte String name; [...] } public class Leaf extends AbstractComponent { [...] } public Composite extends AbstractComponent { private List<Abstra
public abstract class AbstractComponent {
privavte String name;
[...]
}
public class Leaf extends AbstractComponent {
[...]
}
public Composite extends AbstractComponent {
private List<AbstractComponent> children;
public void addChild(AbstractComponent a) {
[...]
}
public List<AbstractComponent> getChildren() {
return children;
}
}
公共抽象类抽象组件{
privavte字符串名称;
[...]
}
公共类叶扩展抽象组件{
[...]
}
公共复合组件{
私有列表)。可以采用我的问题的公认答案吗?我还发现了Guava的TreeTraverser类,但它似乎仅限于一个表示节点的类。迭代器不是递归的。
不确定我是否理解了您的问题,但您的基本迭代器结构应该如下所示(从这里开始的级别顺序:
):
公共类AbstractComponentIterator实现迭代器{
Deque stack=newlinkedlist();
公共抽象组件迭代器(抽象组件根){
stack.add(root);
}
@凌驾
公共布尔hasNext(){
return!stack.isEmpty();
}
@凌驾
公共抽象组件next(){
if(stack.isEmpty()){
抛出新的NoTouchElementException();
}
AbstractComponent节点=stack.pop();
if(node!=null){//仅当Composite.children具有null
if(组合的节点实例){
复合ac=(复合)节点;
对于(抽象组件acc:ac.children){
叠加(acc);
}
}
}
返回节点;
}
}
迭代器不是递归的。
不确定我是否理解了您的问题,但您的基本迭代器结构应该如下所示(从这里开始的级别顺序:
):
公共类AbstractComponentIterator实现迭代器{
Deque stack=newlinkedlist();
公共抽象组件迭代器(抽象组件根){
stack.add(root);
}
@凌驾
公共布尔hasNext(){
return!stack.isEmpty();
}
@凌驾
公共抽象组件next(){
if(stack.isEmpty()){
抛出新的NoTouchElementException();
}
AbstractComponent节点=stack.pop();
if(node!=null){//仅当Composite.children具有null
if(组合的节点实例){
复合ac=(复合)节点;
对于(抽象组件acc:ac.children){
叠加(acc);
}
}
}
返回节点;
}
}
首先是一些术语帮助
- 不是递归的。你要寻找的是一种策略
- 虽然树遍历实现通常是递归的,但它们通常不适用于迭代器
- 组件对象的结构称为
1st您需要选择希望如何遍历复合结构(也称为通用树)
若您并没有特定的遍历顺序要求,那个么这个解决方案是一个很好的选择,因为它易于实现
如果您需要实施不同的策略(例如深度优先),请尝试以下方法
class AbstractComponent {
public Iterator<AbstractComponent> iterator() {
List<AbstractComponent> list = new LinkedList<AbstractComponent>();
addAllChildren(list);
list.add(this);
return list.iterator();
}
protected abstract void addAllChildren(List<AbstractComponent> list);
}
public class Leaf extends AbstractComponent {
//...
protected void addAllChildren(List<AbstractComponent> list) {
//DO NOTHING
}
}
public class Composite extends AbstractComponent {
//...
protected void addAllChildren(List<AbstractComponent> list) {
for (AbstractComponent component : children) {
// This is where you implement your traversal strategy
component.addAllChildren(list);
list.add(component);
}
}
}
类抽象组件{
公共迭代器迭代器(){
列表=新建LinkedList();
添加所有儿童(列表);
列表。添加(此);
return list.iterator();
}
受保护的抽象void addAllChildren(列表);
}
公共类叶扩展抽象组件{
//...
受保护的void addAllChildren(列表){
//无所事事
}
}
公共类复合扩展抽象组件{
//...
受保护的void addAllChildren(列表){
for(抽象组件:子级){
//这就是实现遍历策略的地方
组件.addAllChildren(列表);
列表。添加(组件);
}
}
}
首先是一些术语帮助
- 不是递归的。你要寻找的是一种策略
- 虽然树遍历实现通常是递归的,但它们通常不适用于迭代器
- 组件对象的结构称为
1st您需要选择希望如何遍历复合结构(也称为通用树)
若您并没有特定的遍历顺序要求,那个么这个解决方案是一个很好的选择,因为它易于实现
如果您需要实施不同的策略(例如深度优先),请尝试以下方法
class AbstractComponent {
public Iterator<AbstractComponent> iterator() {
List<AbstractComponent> list = new LinkedList<AbstractComponent>();
addAllChildren(list);
list.add(this);
return list.iterator();
}
protected abstract void addAllChildren(List<AbstractComponent> list);
}
public class Leaf extends AbstractComponent {
//...
protected void addAllChildren(List<AbstractComponent> list) {
//DO NOTHING
}
}
public class Composite extends AbstractComponent {
//...
protected void addAllChildren(List<AbstractComponent> list) {
for (AbstractComponent component : children) {
// This is where you implement your traversal strategy
component.addAllChildren(list);
list.add(component);
}
}
}
类抽象组件{
公共迭代器迭代器(){
列表=新建LinkedList();
添加所有儿童(列表);
列表。添加(此);
return list.iterator();
}
受保护的抽象void addAllChildren(列表);
}
公共类叶扩展抽象组件{
//...
受保护的void addAllChildren(列表){
//无所事事
}
}
公共类复合扩展抽象组件{
//...
受保护的void addAllChildren(列表){
for(抽象组件:子级){
//这就是实现遍历策略的地方
组件.addAllChildren(列表);
列表。添加(组件);
}
}
}
很好的解决方案,我非常喜欢它的简单性。当堆栈为空时,stack.pop()
抛出NoSuchElementException`。它不返回null。@saka1029 java.util.Iterator.next假设在迭代没有更多元素时抛出NoSuchElementException;如果为true,我可以让它更清楚,然后自己抛出它。如果Composite.children有一个null的解决方案,我非常喜欢它的简单性ack为空,stack.pop()
抛出NoSuchElementException`。它不返回null。@saka1029 java.util.Iterator。下一步假设在迭代没有更多元素的情况下抛出NoSuchElementException;如果为true,我可以更清楚地说明它并亲自抛出它。如果Composite.children有一点null(内存),则会进行null检查浪费不?一点(记忆)浪费不?