2

I'm new to Java and I'm making a multi-level console menu. I have an Item class, which has an ArrayList that could contain another Items with own ArrayLists of Items and so on.

public Item(String key, String name, ArrayList<Item> itemList) {
    this.key = key;
    this.name = name;
    this.itemList = itemList;
} 

I need to do info() (or any other method) of each Itemin all arrays (no matter how many nested arrays with Item objects we could have). I wrote some bad and not universal code executing method only of 3-level menu...

public void show() {
    for (int i = 0; i != list.size(); i++) {
        System.out.println(list.get(i).info());
        if (!list.get(i).getItemList().isEmpty()) {
            for (int j = 0; j < list.get(i).getItemList().size(); j++) {
                System.out.println(list.get(i).getItemList().get(j).info());
                if (!list.get(i).getItemList().get(j).getItemList().isEmpty()) {
                    for (int y = 0; y < list.get(i).getItemList().get(j).getItemList().size(); y++) {
                        System.out.println(list.get(i).getItemList().get(j).getItemList().get(y).info());
                    }
                }
            }
        }
    }
}

The result of it look like:

1. Section one.
1.1. Sub-Section one.
1.1.1. Sub-Sub-Section one.

Is there any universal way to loop all Items if we don't know the menu depth?

2 Answers 2

4

You need recursive programming.

Not gonna lie, I'm not a Java programmer but here's my attempt at it:


public void show(List<Item> list) {
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i).info());

        if (!list.get(i).getItemList().isEmpty()) {
            show(list.get(i).getItemList());
        }
    }
}

Or with a for-each:


public void show(List<Item> list) {
    for (Item item : list) {
        System.out.println(item.info());

        if(!item.getItemList().isEmpty()) {
            show(item.getItemList());
        }
    }
 }

This basically loops through your initial list, then print the info. If it contains another item list, then pass that sub item list back to itself. It will then loop through that list you've past and it goes on until there are no more sub item lists.

Sign up to request clarification or add additional context in comments.

2 Comments

The isEmpty check is not actually needed as it just won't loop when its empty. Though if the ItemList can be null, a null-check would be in place there.
Thanks. You helped me a lot :)
-1

Nelson is right on the recursive call. But I feel the base case should different. Because ArrayList may not be empty at the same time it might have Item Object which is not an ArrayList type. So the recursive call will fail. Please see my inline comments.

                import java.util.ArrayList;

        class Item {
            String key;
            String name;
            ArrayList<Item> itemList;
            static int count = 0;

            public Item(String key, String name, ArrayList<Item> itemList) {
                this.key = key;
                this.name = name;
                this.itemList = itemList;
            }

            public int info() {
                return count++;
            }

            public String getKey() {
                return key;
            }

            public void setKey(String key) {
                this.key = key;
            }

            public String getName() {
                return name;
            }

            public void setName(String name) {
                this.name = name;
            }

            public ArrayList<Item> getItemList() {
                return itemList;
            }

            public void setItemList(ArrayList<Item> itemList) {
                this.itemList = itemList;
            } 
        }

        public class recursiveShow {
            public static void main(String[] str) {
                ArrayList<Item> list = new ArrayList<>();
                for(int i = 0; i < 10; i++) {
                    ArrayList<Item> list2 = new ArrayList<>();
                    for(int j = 0; j < 10; j++) {
                        ArrayList<Item> list3 = new ArrayList<>();
                        Item item = new Item("", "", list3);
                        list2.add(item);
                    }
                    Item item = new Item("", "", list2);
                    list.add(item);
                }
                show(list);  //wrong one
                System.out.println("******");
                show2(list);   // funtion given by Nelson
            }

            public static void show2(ArrayList<Item> list) {
                for (Item item : list) {
                    System.out.println(item.info());

                    if(!item.getItemList().isEmpty()) {
                        show(item.getItemList());
                    }
                }
            }

            public static void show(ArrayList<Item> list) {  
                    //if you list is empty, size of the list will be 0 
                    //And you for loop will not run
                    for (int i = 0; i < list.size(); i++) {
                        if(list.get(i).getClass().getName().equals("Item")) { 
                            //Base case for recursion
                            System.out.println(list.get(i).info());
                        } else {
                            //recursive call
                            show(list.get(i).getItemList());
                        }
                    }
                }
        }

3 Comments

That doesn't make sense.. the base case is when the list is empty, nothing happens. When the list is not empty, for each item the function is called again.
This will actually print the info twice, and will never do a recursive call. (If the Items in the list are not subclasses, and if you do String compairison correctly!)
@NickL Yes my answer is incorrect. I updated my code with one test case. Nelson seems correct to me, but i didnot understood why is giving count as 109 for Nelson function? As i have added only 100 items totally

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.