0

I have an object class which is contains a list of itself... Something like this:

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

The childItem also can conatain list of child items. My question is, can I iterate over childItems in all levels?

Right now my code looks like this:

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

Many thanks.

1
  • what is the problem with the code you have shown? It appears to do exactly what you want to achieve. Commented Jul 30, 2017 at 8:42

5 Answers 5

1

There is one error: at the start of the method, you set SearchItemType element = new SearchItemType(); but then check for null when you recurse. element will never be null. You can fix this by setting it to null at the start, but I have some suggestions about your code:

  • Instead of assigning the found value to an element and setting a found flag, just return the object as soon as you find it. At the end of the method return null. This will be much clearer.
  • Iterating over the children and checking them will currently be executed even if the parent was the one that was searched for. In fact, you can remove this loop entirely, as it is handled by the recursive step below.
  • Why are you passing found as a parameter? If you pass it true, then there is no point in having it, so if you really need it, just instantiate it in the method.
  • Make sure to check that gridResult is not null. You could remedy this by making getElementByOpenedRowID a method on SearchItemType, meaning that gridResult does not need to be passed.

Applying these changes will result in:

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;
}
Sign up to request clarification or add additional context in comments.

Comments

0

You can do this with recursion:

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

Comments

0

Yes you can iterate on childItem object at any level as long as childItem is not null and object inside it has non-null values.

In Data structure implementation of LinkedList every node in the LinkedList has Data fields link to other nodes (In case of Java it's reference to other nodes).

It's also called as self referencing objects that means object pointing to object of similar type.

As long as you have non-null values in the list you can iterate at any level.

Data structures in Java are implemented in similar manner. Have look at Node class in this code snippet: Linked List implementation using self referencing pointers

Comments

0

You want to iterate through the children recursively as so:

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

Comments

0

I played around by creating an iterator.

See this:

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

The result is:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.