复合模式的递归迭代器

Recursive iterator for composite pattern

我有树 classes AbstractComponent、Leaf 和 Composite:

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;
    }
}

我的问题:如何在 Java 中为基于复合模式的模型编写递归迭代器?我读了这个问题 (Creating a recursive iterator)。可以对我的问题采用公认的答案吗?我还从番石榴中找到了 TreeTraverser class,但它似乎仅限于一个代表节点的 class。

迭代器不是递归的。 不确定我是否理解你的问题,但你的结构的基本迭代器应该看起来像(从这里开始的级别顺序: http://en.wikipedia.org/wiki/Tree_traversal) :

 public class AbstractComponentIterator implements Iterator<AbstractComponent> {

    Deque<AbstractComponent> stack = new LinkedList<>();


    public AbstractComponentIterator(AbstractComponent root) {
        stack.add(root);
    }

    @Override
    public boolean hasNext() {
        return !stack.isEmpty();
    }

      @Override
    public AbstractComponent next() {
        if(stack.isEmpty()){
            throw new NoSuchElementException();
        }
        AbstractComponent node = stack.pop();
        if (node != null) { //only if Composite.children has null 
            if (node instanceof Composite) {
                Composite ac = (Composite) node;
                for (AbstractComponent acc : ac.children) { 
                    stack.add(acc);
                }
            }
        }
        return node;
    }
}

首先是一些术语方面的帮助。

  • Iterators are not recursive. What you are looking for is a strategy of Tree Traversal

  • 虽然树遍历实现通常是递归的,但它们通常不会用于迭代器。

  • 您的组件对象的结构称为 generic tree

1st 您需要选择遍历复合结构的方式(a.k.a 通用树)

user1121883's 如果您没有特定的遍历顺序要求,解决方案是一个很好的选择,因为它实施起来很简单。

如果您需要实施不同的策略(例如深度优先),请尝试以下方法

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);
        }
    }
}