【问题标题】:How can I get the list of all the items nested(hierarchy) within the item based on parent-child relationship?如何根据父子关系获取项目内所有嵌套(层次结构)项目的列表?
【发布时间】:2016-07-12 13:47:55
【问题描述】:

这有点难以解释。在此示例代码中:

public class SomeClass
{
    private String id;
    private String parent;

    public SomeClass(String id, String parent)
    {
        this.id = id;
        this.parent = parent;
    }

    public String getParent()
    {
        return parent;
    }
}

List<SomeClass> someList = new ArrayList();
someList.add(new SomeClass("Test1", "none"));
someList.add(new SomeClass("Test2", "none"));
someList.add(new SomeClass("Test1Mem1", "Test1"));
someList.add(new SomeClass("Test2Mem1", "Test2"));
someList.add(new SomeClass("Test1Mem1Obj1", "Test1Mem1"));

我想创建一个函数,该函数将使用“父”字段获取包含其层次结构中的对象的所有对象。例如,如果我查找“Test1Mem1Obj1”,它应该给我“{Test1Mem1,Test1}”的值,如果我查找“Test2Mem1”,它应该给我“{Test2}”的值。基本上是获取父级的父级的父级等等。由于语言障碍,我很抱歉这个解释。我希望有人可以在这里帮助我。谢谢!

我有一个临时的肮脏解决方案,你可以明白为什么这不好。

if(someObj.getParent() != null)
{   
    result.add(someObj.getParent());

    if(someObj.getParent().getParent() != null)
    {
        result.add(someObj.getParent().getParent());

        if(someObj.getParent().getParent().getParent() != null)
        {
            result.add(someObj.getParent().getParent().getParent());
        }
    }
}

【问题讨论】:

  • 是否需要使用List?我认为树结构在这里可能会更好。
  • 另外我应该提到我从 MySQL 数据库加载列表。所以它没有任何顺序并且在实现上受到限制,我不能使用树结构。
  • ID 是唯一的吗?你能用地图代替吗?
  • 是的,id 是唯一的,在我的原始代码中,我使用的是 Map 而不是 List。我简化了这个例子,以便更好地解释。

标签: java parent-child hierarchy


【解决方案1】:

如果您可以让getParent() 返回SomeClass 而不是String,那就很简单了:

public boolean isDescendantOf(String parentName) { // part of SomeClass
    SomeClass parent = this.parent;
    while (!parent.id.equals("none")) { // or null check
        if (parent.id.equals(parentName)) {
            return true; // found a parent named parentName
        }
    }
    return false; // eventually reached a parentless parent and never found one matching parentName
}

不过,这也许是不可能的。如果你可以把东西放在地图中,像这样:

Map<String, SomeClass> map = new HashMap<>(); // map from parent name to SomeClass
map.put("Test1", new SomeClass("Test1", "none"));
map.put("Test2", new SomeClass("Test2", "none"));
map.put("Test1Mem1", new SomeClass("Test1Mem1", "Test1"));
map.put("Test2Mem1", new SomeClass("Test2Mem1", "Test2"));
map.put("Test1Mem1Obj1", new SomeClass("Test1Mem1Obj1", "Test1Mem1"));

然后你可以像这样循环遍历它,使用递归:

public boolean isDescendentOf(SomeClass child, String parentName) {
    SomeClass parent = map.get(child.parent);
    if (parent == null) {
        throw new RuntimeException("Warning: parent doesn't exist!");
    }
    if (parent.id.equals(parentName)) {
        return true;
    } else {
        return isDescendentOf(parent, parentName);
    }
}

如果您想为给定元素填充所有父元素的列表,请调用如下函数:

public static void PopulateParents(List<String> parents, Map<String, ClassTest> nodes, ClassTest child) {
    if (child.parent.equals("none")) {
        return;
    }
    ClassTest parent = nodes.get(child.parent);
    if (parent == null) {
        throw new RuntimeException("No parent exists called " + child.parent);
    }
    parents.add(parent.id);
    PopulateParents(parents, nodes, parent);
}

【讨论】:

  • 感谢您的回复。刚发布你的解决方案,我就想出了一个解决方案。现在如果我可以问我是否在这里有效地做到这一点:hastebin.com/faqazagoze.avrasm
  • 您是否要打印出 SomeTest 的所有父母、祖父母等?
  • 是的。你认为我可能会得到 stackoverflow 吗?
  • 好的,我添加了一个递归方法来填充父母列表。
猜你喜欢
  • 2019-10-08
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多