【问题标题】:Why is my program showing this error?为什么我的程序显示此错误?
【发布时间】:2014-10-19 06:14:29
【问题描述】:

我已经查看了一个小时,但我不明白为什么它一直告诉我同样的错误。 对于那些想知道我的程序是什么的人,基本上它会读取一个包含条形码、名称和价格的文本文件。然后,我将读取另一个仅包含条形码的文本文件,并打印其各自的名称和价格。 不幸的是,它只打印一行,然后显示此错误:-

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 99, Size: 99
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.get(ArrayList.java:411)
    at javaapplication9.JavaApplication9.Search(JavaApplication9.java:66)
    at javaapplication9.JavaApplication9.main(JavaApplication9.java:85)

主要

public class JavaApplication9 
{
    long value1;
    String value2;
    double value3;
    ArrayList<String> toBeSplit = new ArrayList(); 
    String[] split;
    ArrayList <Inventory> productList = new ArrayList<> ();
    ArrayList <Long> barcodes = new ArrayList ();

    public long ReadFile(String sfile) throws IOException 
            {       
                int x = 0;
                File inFile = new File(sfile);
                BufferedReader reader = new BufferedReader(new FileReader(inFile));
                String sline = null;
                while ((sline=reader.readLine()) != null) 
                    {
                        toBeSplit.add(x,sline);
                        x++;
                    }
                reader.close();  
                return inFile.length();
            }

    public void splitString ()
    {   
        int a = 0;
        while (a<toBeSplit.size())
        {
            split = toBeSplit.get(a).split(",");            
            value1 = Long.parseLong(split[0]);
            value2 = split[1];
            value3 = Double.parseDouble(split[2]);
            productList.add(new Inventory (value1,value2,value3,split[0]));
            a++;
        }
    }

     public long readBarcodes (String file) throws IOException 
            {       
                File text = new File(file);
                int x = 0;
                BufferedReader reader = new BufferedReader(new FileReader(text));
                String line = null;
                while ((line=reader.readLine()) != null) 
                    {
                        long barcod = Long.parseLong (line);
                        barcodes.add(x,barcod);
                        x++;
                    }
                reader.close();  
                return text.length();
            }

     public void Search()
     {
         int size = barcodes.size();
         int counter = 0;
         for (Inventory e : productList)
            {
                if ((e.getBarcode() - barcodes.get(counter) == 0) && counter <= size)
                {
                    System.out.println (e.getRBarcode()+ "\t" + e.getName() + "\t"+ e.getPrice());
                }
                else
                {
                    counter++;
                }
            }
     }

    public static void main(String[] args)  
    { 
        try
        {
            JavaApplication9 instance = new JavaApplication9 ();
            instance.ReadFile("Products (1).csv");
            instance.splitString();
            instance.readBarcodes("Items.txt");
            instance.Search();

        }
        catch (IOException e)
        {
            System.out.print ("Error");
        }
    } 
}

库存类

public class Inventory
{
    long barcode;
    String name,realBar;
    double price;

   public Inventory (long bars,String pname,double prices,String realBarcode)
    {
        barcode = bars;
        name = pname;
        price = prices;
        realBar = realBarcode;   
    }

    public long getBarcode ()
    {
        return barcode;
    }

    public String getName ()
    {
        return name;
    }

    public String getRBarcode()
    {
        return realBar;
    }

    public double getPrice ()
    {
        return price;
    }
}

【问题讨论】:

  • 看起来像 Off-by-One 错误
  • 错误信息实际上告诉你所有必要的细节来找到问题的确切位置。该程序尝试访问最后一个元素,它发生在文件JavaApplication9.java的第66行

标签: java arrays


【解决方案1】:

在您的 Search 方法中,当您说 barcodes.size() 时,您会得到实际大小。

现在,counter 是从零开始的,在您的 for 循环中,您正在执行 barcodes.get(counter),它实际上一直到 barcodes 大小 + 1。此外,counter &lt;= size 有点让它达到该值。

所以,你需要做的就是改变

if ((e.getBarcode() - barcodes.get(counter) == 0) &amp;&amp; counter &lt;= size)

if (counter &lt; size &amp;&amp; (e.getBarcode() - barcodes.get(counter) == 0))

【讨论】:

    【解决方案2】:

    从错误中,我们看到您正在尝试访问仅包含 99 项的 Arraylist 的索引 99。请记住,索引从0 开始,因此您只能在“越界”之前到达98(这将为您提供上面看到的IndexOutOfBoundsException。)

    IndexOutOfBoundsException 告诉我们这条线是罪魁祸首:

    if ((e.getBarcode() - barcodes.get(counter) == 0) && counter <= size)
    

    counter0 开始,这很好,但您允许counter 到达size,即99,因为您没有任何限制。一旦counter 达到99,您尝试执行barcodes.get(counter),这当然会给您一个IndexOutOfBoundsException,因为99 超出了barcodes 的范围。

    尝试在你的 for 循环中添加一个预防性 if 语句,在其他任何事情之前,当计数器变得太高时添加到 break

    for (Inventory e : productList)
    {
        if (counter == size)
            break;
        if ((e.getBarcode() - barcodes.get(counter) == 0) && counter <= size)
        {
            System.out.println (e.getRBarcode()+ "\t" + e.getName() + "\t"+ e.getPrice());
        }
        else
        {
            counter++;
        }
    }
    

    另一种解决方案是修改您的 if 语句。如果将&lt;=更改为&lt;,然后重新排列语句的求值顺序,就可以防止出现这个异常:

    if (counter < size && (e.getBarcode() - barcodes.get(counter) == 0))
    

    在这种情况下,一旦计数器达到99,它将在counter &lt; size 上评估为假,并且由于双与号(&amp;&amp;),不会评估 if 语句的后半部分,所以它将继续到 else 语句。

    让我知道这是否适合你。

    【讨论】:

    • 或者把counter &lt;= size改成counter &lt; size
    • @Takendarkk 我认为这行不通,因为如果计数器达到 99,第一个 if 语句将返回 false,所以它会转到仅向计数器加 1 的 else。一旦循环再次继续,它将再次尝试在 if 语句中执行barcodes.get(counter),并再次抛出异常。您还必须重新排列 if 语句才能使该更改生效。我编辑了答案以包含此解决方案。
    【解决方案3】:

    在您的Search 方法中,barcodes.size() 为您提供ArrayList 的实际大小。 但是,您的计数器是从0 开始的。 因此,尝试改变

    if ((e.getBarcode() - barcodes.get(counter) == 0) && counter <= size)
    

    到:

    if ((counter < size) && (e.getBarcode() - barcodes.get(counter) == 0))
    

    【讨论】:

    • 您还必须切换两次评估的顺序,否则将首先评估barcodes.get(counter)。如果计数器为 99,则首先 if 语句将尝试 (e.getBarcode() -barcodes.get(counter) == 0),其中包括barcodes.get(counter),这将引发异常,所以另一半if 语句永远不会被评估并且是无用的。改变他们的顺序可以解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2014-06-25
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多