如何遍历嵌套 java 对象列表?

问题描述 投票:0回答:5

我有一个对象类,它包含它自己的列表......像这样:

public class SearchItemType implements Serializable {
  protected List<SearchItemType> childItem;
}

childItem 还可以包含子项目列表。我的问题是,我可以迭代所有级别的 childItems 吗?

现在我的代码如下所示:

public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId, Boolean found) {
        SearchItemType element = new SearchItemType();

        if (gridResult.getId().equals(selectedRowId)) {
            element = gridResult;
            found = true;
        }

        for (SearchItemType child : gridResult.getChildItem()) {
            if (child.getId().equals(selectedRowId)) {
                element = child;
                found = true;
                break;
            }
        }
        if (!found) {
            for (SearchItemType child : gridResult.getChildItem()) {
                element = getElementByOpenedRowID(child, selectedRowId, found);
                checkChildID(child, selectedRowId);
                if (element != null) break;
            }
        }
        return element;
    }

非常感谢。

java arraylist nested
5个回答
1
投票

有一个错误:在方法开始时,您设置了

SearchItemType element = new SearchItemType();
,但在递归时检查
null
element
永远不会为空。您可以通过在开始时将其设置为
null
来解决此问题,但我对您的代码有一些建议:

  • 无需将找到的值分配给元素并设置
    found
    标志,只需在找到对象后立即返回该对象即可。方法结束时返回
    null
    。这样就清楚多了。
  • 即使父级是被搜索的,当前也会执行迭代子级并检查它们。事实上,您可以完全删除此循环,因为它是由下面的递归步骤处理的。
  • 为什么要传递
    found
    作为参数?如果你传递了它
    true
    ,那么拥有它就没有意义了,所以如果你真的需要它,只需在方法中实例化它即可。
  • 确保检查
    gridResult
    不为空。您可以通过将
    getElementByOpenedRowID
    作为
    SearchItemType
    的方法来解决此问题,这意味着不需要传递
    gridResult

应用这些更改将导致:

public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId) {
    // stop at null
    if (gridResult == null) {
        return null;
    }
    if (gridResult.getId().equals(selectedRowId)) {
        return gridResult; // return once found
    }

    // check all of the children
    for (SearchItemType child : gridResult.getChildItem()) {
        // do the search again for every child
        SearchItemType result = getElementByOpenedRowID(child, selectedRowId);
        if (result != null) {
            // return once found and sent it all the way to the top
            return result;
        }
    }
    return null;
}

0
投票

您可以通过递归来做到这一点:

public void iterate(SearchItemType type) {
    // Do something with type
    for (SearchItemType child in type.childItem) {
        iterate(child);
    }
}

0
投票

是的,只要

childItem
不为 null 并且其中的对象具有非空值,您就可以在任何级别迭代
childItem
对象。

在 LinkedList 的数据结构实现中,LinkedList 中的每个节点都有

Data
字段链接到其他节点(在 Java 中,它是对其他节点的引用)。

也称为自引用对象,即指向相似类型的对象的对象。

只要列表中有非空值,您就可以在任何级别进行迭代。

Java
中的数据结构以类似的方式实现。 看一下这段代码片段中的
Node class
使用自引用指针实现链表


0
投票

您想像这样递归地遍历子级:

public SearchItemType getElementByOpenedRowID(SearchItemType gridResult, String selectedRowId) {
    SearchItemType element = null;
    if (gridResult == null) return null;
    else if (gridResult.getId().equals(selectedRowId)) return gridResult;
    else {
        for (SearchItemType child : gridResult.getChildItem()) {
            element = getElementByOpenedRowID(child, selectedRowId);
            if (element != null) break;
        }
    }
    return element;
}

0
投票

我通过创建一个迭代器进行了尝试。

看这个:

public class SearchItemType {
    protected List<SearchItemType> childItem = new ArrayList();
    protected String id;

    public SearchItemType(String id) {
        this.id = id;
    }

    public static void main(String[] args) {
        SearchItemType one = new SearchItemType("1");
        SearchItemType one_one = new SearchItemType("1.1");
        SearchItemType one_two = new SearchItemType("1.2");
        SearchItemType one_three = new SearchItemType("1.3");
        SearchItemType one_four = new SearchItemType("1.4");
        SearchItemType one_two_one = new SearchItemType("1.2.1");
        SearchItemType one_two_two = new SearchItemType("1.2.2");
        SearchItemType one_two_three = new SearchItemType("1.2.3");
        SearchItemType one_three_one = new SearchItemType("1.3.1");
        SearchItemType one_three_two = new SearchItemType("1.3.2");
        SearchItemType one_three_three = new SearchItemType("1.3.3");
        SearchItemType one_three_two_one = new SearchItemType("1.3.2.1");
        SearchItemType one_three_two_two = new SearchItemType("1.3.2.2");
        one.childItem.add(one_one);
        one.childItem.add(one_two);
        one.childItem.add(one_three);
        one.childItem.add(one_four);
        one_two.childItem.add(one_two_one);
        one_two.childItem.add(one_two_two);
        one_two.childItem.add(one_two_three);
        one_three.childItem.add(one_three_one);
        one_three.childItem.add(one_three_two);
        one_three.childItem.add(one_three_three);
        one_three_two.childItem.add(one_three_two_one);
        one_three_two.childItem.add(one_three_two_two);

        Iterator<SearchItemType> itr = one.getItemTypeIterator();
        while (itr.hasNext())
            System.out.println(itr.next().id);
    }

    public Iterator<SearchItemType> getItemTypeIterator() {
        return new Iterator<SearchItemType>() {
            ArrayList<SearchItemType> parents = new ArrayList();
            SearchItemType next = null;
            boolean avoidChildren = false, nextSearched = false;

            public boolean hasNext() {
                if (!nextSearched)
                    searchNext();
                nextSearched = true;
                return next != null;
            }

            public SearchItemType next() {
                if (!nextSearched)
                    searchNext();
                nextSearched = false;
                return next;
            }

            private void searchNext() {
                if (next == null) {
                    next = SearchItemType.this;
                    return;
                }

                if (!avoidChildren) {
                    if (next.childItem.size() > 0) {
                        parents.add(next);
                        next = next.childItem.get(0);
                    } else {
                        avoidChildren = true;
                    }
                }

                if (avoidChildren) {
                    while (parents.size() > 0) {
                        SearchItemType lastParent = parents.get(parents.size() - 1);
                        int i = lastParent.childItem.indexOf(next);
                        if (i < lastParent.childItem.size() - 1) {
                            next = lastParent.childItem.get(i + 1);
                            avoidChildren = false;
                            return;
                        } else {
                            next = lastParent;
                            parents.remove(parents.size() - 1);
                        }
                    }
                    next = null;
                }
            }
        };
    }
}

结果是:

1
1.1
1.2
1.2.1
1.2.2
1.2.3
1.3
1.3.1
1.3.2
1.3.2.1
1.3.2.2
1.3.3
1.4
© www.soinside.com 2019 - 2024. All rights reserved.