复合模式的递归迭代器

时间:2015-06-11 11:28:20

标签: java iterator composite

我有树类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)。有可能采用我的问题的公认答案?我还从Guava中找到了TreeTraverser类,但它似乎仅限于一个代表节点的类。

2 个答案:

答案 0 :(得分:3)

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

class TemplateAttributeForm(forms.ModelForm):
    class Meta:
        model = Template
    def __init__(self,*args, **kwargs):
        super(TemplateAttributeForm, self).__init__(*args, **kwargs) 
        self.fields['attribute'].queryset = Attribute.objects.filter(#WANT TO FILTER BY THE ID OF THE COMPANY THAT OWNS THE TEMPLATE WE ARE EDITING ON THE ADMIN PAGE)

答案 1 :(得分:3)

首先提供一些术语帮助。

  • Iterators不是递归的。您正在寻找的是Tree Traversal的策略。

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

  • Component对象的结构称为generic tree

第一您需要选择如何遍历复合结构(a.k.a Generic Tree)

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