使用数组/ArrayList实现多类ListToDo时遇索引越界异常求助
嘿,我来帮你搞定这个头疼的异常!先看看你遇到的错误:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0 at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:665) at java.util.ArrayList.add(ArrayList.java:477) at ToDoList.addTask(ListToDo.java:213) at ToDoList.displayMenu(ListToDo.java:272) at ToDoList.main(ListToDo.java:188)
这个异常的核心原因很明确:你试图往一个空的ArrayList里插入索引1的位置,但空列表的有效插入索引只能是0。
问题代码分析
先看你的add方法:
public void add(Task newTask){ list.add(newTask.getTaskID(), newTask); }
当你第一次添加任务时,list的size是0,但你的newTask.getTaskID()返回了1(从你输出的Task 1 is added能看出来),这就违反了ArrayList的add(int index, E element)规则——这个方法要求索引必须满足0 ≤ index ≤ list.size(),空列表时只能插入到索引0的位置。
另外你的print方法还有个隐藏bug:
public void print(Task[] newTask){ list.addAll(Arrays.asList(newTask)); list.size(); menu(); } // 调用时的代码: Task[] newTask1 = new Task[0]; newTask1[0] = new Task(time,date,title,location); toDoList.print(newTask1);
你创建了一个长度为0的数组,然后试图给索引0赋值,这会直接触发ArrayIndexOutOfBoundsException,因为长度为0的数组没有任何元素位置。
还有个小问题:menu方法里递归调用自己,多次操作后容易导致栈溢出,应该用循环替代递归。
修复方案
1. 修复add方法
不要用任务ID作为ArrayList的插入索引(任务ID是业务标识,和列表的位置索引不是一回事),直接把任务添加到列表末尾即可:
public void add(Task newTask){ // 如果需要任务ID自增,可以在这里设置 newTask.setTaskID(list.size() + 1); // 假设Task类有setTaskID方法 list.add(newTask); // 添加到列表末尾 }
如果你的TaskID是在Task类内部生成的,确保新任务的ID从1开始,且后续任务ID正确递增,但绝对不要用它来作为ArrayList的插入索引。
2. 重构print方法
不需要传入数组,直接打印当前列表的所有任务即可:
public void print(){ System.out.println("当前待办列表:"); for(Task task : list){ // 假设Task类重写了toString方法,输出任务详情 System.out.println(task); } }
然后在菜单的case1里,直接调用toDoList.print(),删掉那个错误的数组创建代码。
3. 用循环替代递归菜单
把递归调用改成while循环,避免栈溢出:
private static void menu(){ Scanner input = new Scanner(System.in); ListToDo toDoList = new ListToDo(); boolean isRunning = true; while(isRunning){ System.out.println("\n=== 待办事项菜单 ==="); System.out.println("1: 添加任务"); System.out.println("0: 退出"); System.out.print("请选择操作:"); int option = input.nextInt(); input.nextLine(); // 吃掉换行符,避免后续输入问题 switch(option){ case 1: System.out.print("请输入任务标题:"); String title = input.nextLine(); System.out.print("请输入任务日期(dd mm yyyy):"); int day = input.nextInt(); int month = input.nextInt(); int year = input.nextInt(); System.out.print("请输入开始时间(hh mm):"); int hour = input.nextInt(); int min = input.nextInt(); input.nextLine(); // 吃掉换行符 System.out.print("请输入地点:"); String location = input.nextLine(); Time time = new Time(hour, min); Date date = new Date(day, month, year); Task newTask = new Task(time, date, title, location); toDoList.add(newTask); System.out.println("任务 " + newTask.getTaskID() + " 已添加!"); toDoList.print(); break; case 0: isRunning = false; System.out.println("再见!"); break; default: System.out.println("错误!请选择列表中的操作!"); } } input.close(); }
这样修改后,你的代码就能正常添加任务,也不会再触发索引越界的异常了。
内容的提问来源于stack exchange,提问作者J.WilliamJoneson

