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);
}
}
如何在不同的 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);
}
}