2016-08-10 2 views
-2

Как реализовать однопроцессорную итерацию по иерархии разных объектов?Одиночная итерация по иерархии в Java 8

(я использовал для петель, но они представляют собой различные области сетки - я едва могу следовать все значения, которые используются для позиционирования Использование одного цикла будет существенно упростить.).

Этот иерархия объектов это то, что у меня есть ....

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 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();, потому что р имеет тип планеты

Редактировать:. Это должно быть «Глубина-Last» (... или FIFO ?) Цикл - это упрощение генерации пользовательского интерфейса, поэтому порядок важен.

+2

https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/TreeTraverser.html –

+0

Итак, вы хотите итератор, который пересекает весь суб-иерархии конкретного узла? Вы хотите сначала сначала глубину, или дыхание? – Andreas

+0

Спасибо, Андреас. Я не думаю, что это «первый» или «последний», но вместо этого «встречается». Я думаю, что Рамсей уже опубликовал достойный ответ, используя рекурсию.Я не могу сказать, что я влюблен в результат, но он должен работать. –

ответ

0

Если я понял, что вы прав, вы хотите, чтобы иметь возможность посещать каждый объект в графе объектов и что-то делать с каждым объектом?

Когда каждый объект реализует общий интерфейс, как и ваш, это просто разрешается с помощью рекурсии. Ваше единственное решение - хотите ли вы сначала выполнить реверсию глубины или ширину?

Для глубины первой, вы хотели бы что-то вроде

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

Глубина первого не работает для пользовательского интерфейса. Извинения, которые я не объяснял, это перебрать многоуровневые переменные для отображения на сетке. Порядок важен. (Добавлено редактирование оригинального сообщения.) –

+0

Обновленный ответ, чтобы включить в себя ширину. –

+0

Да, я вижу, что вы делаете сейчас! С небольшой настройкой это должно работать нормально. Скоро опубликую мои изменения. Спасибо. = D –

Смежные вопросы