Java 8中的层次结构上的单次迭代

时间:2016-08-10 21:18:15

标签: java javafx collections iterator hierarchy

如何在不同对象的层次结构上实现单循环迭代?

(我使用过for循环,但这些代表网格的不同区域 - 我几乎无法跟踪用于定位的所有值。使用单个循环可以大大简化事情。) < / p>

这个对象的层次结构就是我的......

class Hierarchical < PT extends Hierarchical<?,?,?>,T,CT extends Hierarchical< ?, ?, ? >>{
    ObservableList< Hierarchical > children;  //Zero or more objects..
}

class Seed   extends Hierarchical { /* never has children-objects */ }
class Tree   extends Hierarchical { ... }
class Planet extends Hierarchical { ... }

编辑:Planet实例中的子项是树,对于包含种子的树来说是相同的。

......这就是我想要做的事情:

Planet p = new Planet(); //trees/seeds are instantiated internally.
Iterator< ? > itr = p.getChildren().iterator();
while ( itr.hasNext() ) {
    Object obj = itr.next();
    if ( obj instanceof Planet ){ /* cast to Planet & do stuff */ }
    if ( obj instanceof Tree   ){ /* cast to Tree   & do stuff */ }
    if ( obj instanceof Seed   ){ /* cast to Seed   & do stuff */ }
}

显然,答案在于Iterator< ? > itr = p.getChildren().iterator(); 但是如何实施呢?看起来,等级的每个层次都需要保持其子女的位置,以防孩子开始在孩子身边循环。它已经太久了,我对设计模式并不熟悉。 java的集合了。 :(

我注意到在尝试使用Iterator< Hierarchical > itr = p.getChildren().iterator();时出错,因为p属于Planet类型。

修改:这需要是&#34;深度 - 最后&#34; (......或FIFO?)。循环是为了简化UI的生成,因此顺序很重要。

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您希望能够访问对象图中的每个对象并对每个对象执行某些操作吗?

当每个对象实现一个公共接口时,就像你的那样,只需使用递归即可解决。您唯一的决定是要进行深度优先递归还是广度优先。

对于深度优先,你会想要像

这样的东西
public void visit(Hierarchical h) {
    // do something with h
    Iterator<Hierarchical> children = h.getChildren();
    while(children.hasNext()) {
        visit(children.next());
    }
}
  

似乎层次结构的每个级别都需要保持一个   在孩子开始循环的情况下,孩子的位置   通过他们的孩子

以这种方式使用递归,您不需要跟踪任何位置&#39; - 当你再次调用方法时,迭代器的状态保持在堆栈上,当堆栈展开时,当你到达种子时,你将回滚堆栈一级并调用迭代器的下一次迭代。

对于广度优先,您需要先处理整个节点,然后随时收集分支。处理好所有孩子后,你需要从分支集合开始。

public void visit(Hierarchical h) {
    List<Hierarchical> branches = new LinkedList<>();
    Iterator<Hierarchical> children = h.getChildren();

    while(children.hasNext()) {
        Hierarchical h = children.next();
        // do something with h
        if(h.hasChildren()) {
            branches.add(h);
        }
    }

    for(Hierarchical branch : branches) {
        visit(branch);
    }
}