【问题标题】:Loop of objects in ArrayLists of multi-level menu (Java)多级菜单的ArrayLists中的对象循环(Java)
【发布时间】:2017-05-30 01:01:46
【问题描述】:

我是 Java 新手,我正在制作一个多级控制台菜单。我有一个Item class,它有一个ArrayList,它可以包含另一个具有自己的项目数组列表的项目等等。

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

我需要对所有数组中的每个Item 执行info()(或任何其他方法)(无论我们可以拥有多少个带有 Item 对象的嵌套数组)。我只写了一些糟糕的、不通用的代码执行方法,只有 3 级菜单......

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

结果如下:

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

如果我们不知道菜单深度,是否有任何通用的方法来循环所有项目?

【问题讨论】:

    标签: java loops recursion arraylist menu


    【解决方案1】:

    你需要recursive programming

    不会撒谎,我不是 Java 程序员,但这是我的尝试:

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

    或者使用 for-each:

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

    这基本上会遍历您的初始列表,然后打印信息。如果它包含另一个项目列表,则将该子项目列表传递回自身。然后它会循环遍历你过去的列表,直到没有更多的子项目列表为止。

    【讨论】:

    • isEmpty 检查实际上并不需要,因为它在空时不会循环。虽然如果ItemList 可以是null,则将在那里进行空检查。
    • 谢谢。你帮了我很多:)
    【解决方案2】:

    Nelson 在递归调用上是正确的。但我觉得基本情况应该不同。 因为 ArrayList 可能不会同时为空,所以它可能具有不是 ArrayList 类型的 Item Object。所以递归调用会失败。请查看我的内联 cmets。

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

    【讨论】:

    • 这没有意义.. 基本情况是当列表为空时,没有任何反应。当列表不为空时,对每个项目再次调用该函数。
    • 这实际上会打印两次信息,并且永远不会进行递归调用。 (如果列表中的 Items 不是子类,并且您正确地进行了 String 比较!)
    • @NickL 是的,我的回答不正确。我用一个测试用例更新了我的代码。尼尔森对我来说似乎是正确的,但我不明白为什么尼尔森函数的计数为 109?因为我总共只添加了 100 个项目
    猜你喜欢
    • 2016-03-08
    • 2013-03-22
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2017-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多