Java 复合模式的递归迭代器

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

我有树类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;
    }
}
公共抽象类抽象组件{
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检查浪费不?一点(记忆)浪费不?