【问题标题】:Single-iteration over hierarchy in Java 8Java 8 中层次结构的单次迭代
【发布时间】:2016-08-10 21:18:15
【问题描述】:

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

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

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

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&lt; Hierarchical &gt; itr = p.getChildren().iterator(); 时出错,因为 p 的类型是 Planet。

编辑:这需要是“Depth-Last”(...或 FIFO?)。循环是为了简化 UI 的生成,所以顺序很重要。

【问题讨论】:

  • 那么您想要一个遍历特定节点的整个子层次结构的迭代器吗?你想要深度优先还是呼吸优先?
  • 谢谢安德烈亚斯。我不认为它是“第一个”或“最后一个”,而是“遇到的”。我认为 Ramsay 已经使用递归发布了一个不错的答案。我不能说我爱上了这个结果,但它应该可以工作。

标签: java javafx collections iterator hierarchy


【解决方案1】:

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

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

为了深度优先,你会想要类似的东西

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

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

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

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

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

【讨论】:

  • 深度优先不适用于 UI。抱歉,我没有解释,这是迭代多层变量以显示在网格上。顺序很重要。 (添加了对原始帖子的编辑。)
  • 是的,我明白你现在在做什么!稍作调整,这应该可以正常工作。我会尽快发布我的更改。谢谢你。 =D
猜你喜欢
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多