简体   繁体   English

为什么我得到“ArrayIndexOutOfBoundsException”?

[英]Why did I get an “ArrayIndexOutOfBoundsException”?

I'm pretty new to programming and working on an assignment for class. 我很擅长编程和上课。 Now, I'm not asking for anyone to write my code for me but I'm stuck with a runtime error. 现在,我不是要求任何人为我编写代码,但我遇到了运行时错误。 In the assignment we need to read a file, use the first line, "15", to initialize the size of an array, and proceed to fill the array with the information from each line. 在赋值中我们需要读取一个文件,使用第一行“15”来初始化数组的大小,然后用每行的信息填充数组。

edit: I didn't want to post all of the code because I thought it would look too long but because of the downvotes for being vague, here it goes. 编辑:我不想发布所有的代码,因为我觉得它看起来太长了但是由于模糊的暗示,这就是它。

File: 文件:

15
produce,3554,broccoli,5.99,1
produce,3554,broccoli,5.99,1
produce,3555,carrots,2.23,0.25
produce,3555,carrots,2.23,0.25
produce,3555,carrots,2.23,0.25
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2345,windex,5.99,1 unit
cleaning,2346,toilet paper,12.99,4 rolls
cleaning,2346,toilet paper,12.99,4 rolls
cleaning,2335,windex,2.25,1 mini sprayer
cleaning,1342,wipes,3.99,10 units
cleaning,1342,wipes,3.99,10 units
produce,3546,lettuce,2.99,0.5

My Error: 我的错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
    at Inventory.readFile(Inventory.java:45)
    at Inventory.<init>(Inventory.java:12)
    at Supermarket.main(Supermarket.java:3)

Class with the Line 45 in Question (line 45 is commented, scroll to the right)" 有问题的第45行的类(第45行被评论,向右滚动)“

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

public class Inventory{
    Product[] list;
    String[] invData;
    private int i = 0;
    public int count;

    public Inventory (String f){
        readFile(f);
    }

    public int indexOfProduct(int code){        
        for(i=0; i<list.length; i++){ 
            if (list[i] != null)
                if (list[i].getCode() == code)
                    return i;

        }
        return -1;
    }


    public Product delete(int pos){
        Product temp = new Product();
        temp = list[pos];
        list[pos] = null;
        return temp;
    }

    public void readFile(String fileName){
        try{
            File invList = new File (fileName);
            Scanner s = new Scanner(invList);
            int itemCount = s.nextInt();
            list = new Product[itemCount];
            count = itemCount;
            while (s.hasNext()){
                String line = s.nextLine();
                invData = line.split(",");
                if (invData[0].equals("produce")){
                    list[i] = new Produce(invData[1], invData[2], invData[3], invData[4]); // This is Line 45, Where the error occurs
                } else if(invData[0].equals("cleaning")){
                    list[i] = new Cleaning(invData[1], invData[2], invData[3], invData[4]);
                }
                i++;
            }//end of while loop
        } catch (FileNotFoundException Abra) {
            String error = Abra.getMessage();
            System.out.println(error);
            } 
    } // end of method

    public Product findCode(int c){
        for(int i=0; i<list.length;i++)
            if(list[1].getCode() == c)
                return list[i];
        return null;
    }//end of method
}//end of class

Why did I get an "ArrayIndexOutOfBoundsException"? 为什么我得到“ArrayIndexOutOfBoundsException”? I hope someone can point out the flaw in my logic so I don't repeat it again. 我希望有人可以指出我逻辑中的缺陷,所以我不再重复了。

Your issue is clearly with the use of i , as that is the only variable index on that line, and the out of range index is "15", which is just past the end of your 15-item array. 您的问题显然是使用i ,因为这是该行上唯一的变量索引,超出范围的索引是“15”,这刚刚超过15项数组的末尾。 So, couple of issues, all surrounding the use of i : 那么,几个问题,都围绕着i的使用:

As nhellwig mentioned, be sure that i is actually initialized to 0 before calling this function. 正如nhellwig所提到的,确保在调用此函数之前i实际上已初始化为0。

Additionally, you're putting a lot of faith in the consistency of the item number in the file and the actual number of items. 此外,您非常相信文件中项目编号的一致性和实际的项目数。 You should either produce a warning and stop trying to store items in the array if i >= itemCount , or use a container like an ArrayList that can grow to accommodate new items instead of a fixed size array. 如果i >= itemCount ,您应该产生警告并停止尝试将项目存储在数组中,或者使用像ArrayList这样的容器,它可以增长以容纳新项目而不是固定大小的数组。

Edit: Also, I should point out that you increment i whether you read an item or not, which means even blank lines will increment i , causing gaps in your list or array overruns. 编辑:另外,我要指出,你增加i不管你读的项目或没有,这意味着即使空行会增加i ,在你的列表或阵列超支造成的差距。 Since itemCount is the number if items, you should stick to that and only increment i if you read an actual item. 由于itemCount是项目的数字,因此您应该坚持使用,只有在读取实际项目时才增加i

In that same spirit, you should verify that invData.length == 5 after you call split(), because a misplaced comma, etc. in your file may also end up with an OOB error. 在同样的精神中,你应该在调用split()之后验证invData.length == 5 ,因为文件中错误的逗号等也可能最终出现OOB错误。 Granted, for your project, it's probably OK to make assumptions about the number of elements in a line that starts with "produce" or "cleaning", but in general it's important to be cautious with data coming from a user-created file. 当然,对于您的项目,可以对以“生产”或“清理”开头的行中的元素数量进行假设,但一般来说,对来自用户创建的文件的数据保持谨慎是很重要的。

I found the answer to be that I needed an "s.nextLine();" 我发现答案是我需要一个“s.nextLine();”

Because I used "s.nextInt();" 因为我使用了“s.nextInt();” the pointer was just hangin around at the end of "15" in my file. 指针只是挂在我文件中“15”的末尾。 Then, when the first line in the While loop "String line = s.nextLine();" 然后,当While循环中的第一行“String line = s.nextLine();”时 executed the pointer moved from the end of 15 to before the p in produce in the 2nd line of the list file. 执行指针从15的末尾移动到列表文件的第2行中的p in产生之前。

The working method looks like this: 工作方法如下所示:

public void readFile(String fileName){
    try{
        File invList = new File (fileName);
        Scanner s = new Scanner(invList);
        int itemCount = s.nextInt();
        s.nextLine(); // This is the new line that made it work
        list = new Product[itemCount];
        count = itemCount;
        while (s.hasNext()){
            String line = s.nextLine(); //moves file pointer over one
            invData = line.split(",");
            if (invData[0].equals("produce")){
                list[i] = new Produce(invData[1], invData[2], invData[3], invData[4]);
            } else if(invData[0].equals("cleaning")){
                list[i] = new Cleaning(invData[1], invData[2], invData[3], invData[4]);
            }
            i++;
        }//end of while loop
    } catch (FileNotFoundException Abra) {
        String error = Abra.getMessage();
        System.out.println(error);
        } 
} // end of method

How many times do you call readFile? 你多少次调用readFile? You should have i = 0; 你应该有i = 0; at the beginning of the function. 在功能的开头。

“i”不应该是全局值,而应该是方法局部变量,初始化为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM