Search code examples
javaarraylistnested

How can I iterate throughout on list of nested java objects?


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.


Solution

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