Single-iteration 层次结构 Java 8

Single-iteration over hierarchy in Java 8

如何在不同的 objects 层次结构上实现 single-loop 迭代?

(我使用了 for-loops 但它们代表了网格的不同区域——我几乎无法遵循用于定位的所有值。使用单个循环会大大简化事情。 )

这个objects的层级是我的....

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 { ... }

编辑: Children 在 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(); ,但如何实现呢?似乎层次结构的每个级别都需要保持其 children 的位置,以防其 children 开始循环其 children。时间太久了,我已经不熟悉design-patterns & java的collections了。 :(

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

编辑:这需要"Depth-Last"(...或先进先出?)。循环是为了简化 UI 的生成,因此顺序很重要。

如果我没听错,您希望能够访问对象图中的每个对象并对每个对象执行某些操作?

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

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

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

It would seem that every level of the hierarchy would need to keep a position of it's children in the event its children start looping through their children

以这种方式使用递归,您不需要跟踪任何 'position' - 迭代器的状态在您再次调用该方法时保留在堆栈中,因此随着堆栈展开,当你到达 'seed' 时,你会将堆栈回滚一个级别并调用迭代器的下一次迭代。

对于广度优先,您需要先处理整个节点,边处理边收集分支。处理完所有子项后,您需要开始收集分支。

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