簡體   English   中英

組合模式的遞歸迭代器

[英]Recursive iterator for composite pattern

我有樹類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遞歸迭代器? 我讀了這個問題( 創建一個遞歸迭代器 )。 是否可以對我的問題采用公認的答案? 我還從Guava找到了TreeTraverser類,但它似乎僅限於代表一個節點的一個類。

迭代器不是遞歸的。 不知道我是否理解您的問題,但是適合您的基本迭代器結構應如下所示(從此處進行級別排序: 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;
    }
}

首先,一些術語方面的幫助。

  • 迭代器不是遞歸的。 您正在尋找的是樹遍歷策略。

  • 盡管樹遍歷實現通常是遞歸的,但它們通常不適用於迭代器。

  • Component對象的結構稱為通用樹

首先,您需要選擇如何遍歷復合結構(即通用樹)

如果您沒有特定的遍歷訂單要求,則user1121883的解決方案是一個不錯的選擇,因為它很容易實現。

如果您需要實施其他策略(例如深度優先),請嘗試以下方法

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM