【问题标题】:retrive all childs from N number of levels From Collection从集合中检索 N 个级别的所有子项
【发布时间】:2017-02-07 08:29:57
【问题描述】:

我是收藏新手。 我有以下课程

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。

【问题讨论】:

  • 父子关系是否通过id和PID关联?
  • 为什么要在列表(平面)中表示层次结构?

标签: java arraylist data-structures collections


【解决方案1】:

一个简单的“蛮力”解决方案是:

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

您也可以使用带有简单过滤器的 Java8 流。

当然,这适用于这个简单的字符串比较。 必须澄清的关键是这种“儿童”关系对您实际上意味着。在您的示例中,您只是告诉我们您认为“A112”是“A1”的

所以,为了解决您的评论:如果您想实现真正的分层排序,那么您必须在代码中表达。含义:您可能需要创建自己的 tree 实现;在您添加对象的位置,以及基于您编写的代码,您的树将元素排列在此类“子类”类别中。

换句话说:您当前的代码对字符串进行了简单的假设。如果您需要更复杂的东西;那么,必须实现它。您必须采取的第一步是:为自己阐明如何定义这种关系。这不是我们可以帮助的!

换句话说:现在,你只有那个 Parant 类的对象。并且这些对象彼此之间绝对没有关系。如果你想要这样的关系,你必须在你的类中增加表达它们的方法!例如,将您的课程更改为“节点”课程;并且 Node ... 具有添加/查询 child 节点的方法!

【讨论】:

  • 感谢您的回复。但是假设A1的孩子不是以“A1”开头那我该怎么办?
  • 我更新了我的答案;但请理解,我们能提供的帮助并不多。
  • 我认为您使用该名称来创建父子关系,但 OP 使用的是 id/pid。 id/pid 恰好对应于本例中的名称。
【解决方案2】:

如果您想坚持当前的结构。您可能会制作一种方法来满足您的需求。有两点,

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

【讨论】:

    猜你喜欢
    • 2015-04-05
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2013-11-14
    相关资源
    最近更新 更多