You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用数组/ArrayList实现多类ListToDo时遇索引越界异常求助

解决Java的IndexOutOfBoundsException异常问题

嘿,我来帮你搞定这个头疼的异常!先看看你遇到的错误:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:30:42