2016-09-29 6 views
3

Я новичок в коллекциях. я следующий классИзвлечение всех детей из числа N Количество уровней От коллекции

class ParantCategory { 
    int id; 
    String name; 
    int pid; 
    public ParantCategory(int id, String name, int pid) { 
     this.id = id; 
     this.name = name; 
     this.pid = pid; 
    } 
    public int getId() { 
     return id; 
    } 
    public void setId(int id) { 
     this.id = id; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public int getPid() { 
     return pid; 
    } 
    public void setPid(int pid) { 
     this.pid = pid; 
    } 
} 

И мой основной класс метод, как

public class HierachiDemo { 
    static ArrayList<ParantCategory> al = new ArrayList<>(); 
    public static void main(String[] args) { 
     al.add(new ParantCategory(1, "000", 0)); 
     al.add(new ParantCategory(2, "A1", 1)); 
     al.add(new ParantCategory(3, "B1", 1)); 
     al.add(new ParantCategory(4, "A11", 2)); 
     al.add(new ParantCategory(5, "A12", 2)); 
     al.add(new ParantCategory(6, "A13", 2)); 
     al.add(new ParantCategory(7, "B11", 3)); 
     al.add(new ParantCategory(8, "B12", 3)); 
     al.add(new ParantCategory(9, "B13", 3)); 
     al.add(new ParantCategory(10, "A111", 4)); 
     al.add(new ParantCategory(11, "A112", 4)); 
     al.add(new ParantCategory(12, "A113", 4)); 
     HierachiDemo h = new HierachiDemo(); 
     //function call here 
    } 
} 

Я хранятся элементы в ArrayList. Теперь мой вопрос: мне нужна функция рекурсии, в которой я передам имя, и он даст мне всех детей с n-го уровня. например: Если я передам A1 в качестве имени, тогда он должен вернуть мне всех детей, таких как A11, A12, A13, а также, если у вас есть субшильда A11, A12, A13, которые также должны отображаться. Мне нужен конечный результат как A11, A12, A13, A111, A112, A113.

+0

Связаны ли родители и дети через идентификатор и идентификатор PID? – matt

+0

Почему вы пытаетесь представить иерархическую структуру в списке (плоском)? – Spotted

ответ

3

Простое решение «грубой силы» будет:

List<ParantCategory> matches = new ArrayList<>(); 
for (ParantCatagory parant : al) { 
    if (parant.getName().startsWith("A1")) { 
    matches.add(al); 
    } 
} 

Вы также можете использовать Java8 потоки с помощью простого фильтра вместо этого.

Конечно, это работает для простого сравнения строк. Главное, что вы должны уточнить что такие «детские» отношения фактически означает вам. В вашем примере вы просто сказали нам, что вы считаете, что «A112» является ребенком «A1».

Таким образом, чтобы решить Ваш комментарий: если вы хотите реализовать реальной иерархического упорядочения, то вы должны выразить, что в коде. Значение: чем вам, возможно, придется создать свой собственный tree реализация; где вы добавляете свои объекты, и на основе код, который вы пишете, ваши элементы заказов деревьев в таких категориях «подкласса».

Другими словами: ваш текущий код делает простые предположения о строках. Если вам нужно что-то более сложное; ну, то вы должны реализовать это. И первый шаг, который вы должны предпринять: уточните для себя, как должны быть определены такие отношения. Это ничего, с чем мы можем помочь!

Другими словами: прямо сейчас у вас есть только объекты этого класса Parant. И эти объекты имеют абсолютно no отношения между собой. Если вам нужны такие отношения, вам нужно добавить средства в свой класс, чтобы выразить их! Например, изменив класс на класс «Узел»; и Узел ... есть методы для добавления/запроса child узлов!

+0

Спасибо за ваш ответ. Но предположим, что дочерние элементы A1 не начинаются с «A1», то что мне делать? –

+0

Я обновил свой ответ; но, пожалуйста, поймите, что мы не можем с этим справиться. – GhostCat

+2

Я думаю, что вы использовали имя для создания родительской дочерней связи, но OP использует id/pid. Id/pid по совпадению соответствует именам в этом примере. – matt

1

Если вы хотите придерживаться существующей структуры. Вы можете сделать метод, который делает то, что вы хотите. Есть две вещи,

List<ParantCategory> getChildNodes(String name, int levels){ 
    List<ParantCategory> results = new ArrayList<>(); 
    ParantCategory head = null; 

    //assuming there is only one ParantCategory with the supplied name. 
    for(ParantCategory p: al){ 
     if(name.equals(al.getName())){ 
      head = al; 
      break; 
     } 
    } 

    //if we cannot find the name just use an empty list. 
    if(head==null) return results; 
    results.add(head); 
    results.addAll(getChildren(head.getPid(), levels)); 
    return results; 

}

Мы можем сделать рекурсивный метод для получения детей.

void getChildren(int pid, levels){ 

    if(levels==0) return Collection.emptyList(); 

    List<ParantCategory> results = al.stream().filter(
      p->p.getPid()==pid 
     ).collect(Collectors.toList()); 
    for(ParantCategory p: results){ 
     results.addAll(getChildren(p.getPid(), levels-1)); 
    } 
    return results; 
} 
Смежные вопросы