【问题标题】:How can I fix this exception我该如何解决这个异常
【发布时间】:2014-04-22 21:58:09
【问题描述】:

这是我区分两个 txt 文件之间差异的代码。唯一的问题是,如果我不从 arrayList 中减去 1,我会得到一个越界异常,所以现在它并没有针对所有元素运行,我该如何解决这个问题?

import java.io.*;
import java.util.*;

public class myfilereader
{
    public static void main (String[] args) throws java.io.IOException
    {

        int temp = 0;
        ArrayList<String> ArrayList1 = new ArrayList<String>();
        ArrayList<String> ArrayList2 = new ArrayList<String>();
        ArrayList<String> ArrayList3 = new ArrayList<String>();
        try
        {
            Scanner File1 = new Scanner(new File("/Users/Home/Desktop/File1.txt"));
            while (File1.hasNext())
            {
                ArrayList1.add(File1.next());
            }

            Scanner File2 = new Scanner(new File("/Users/Home/Desktop/File2.txt"));
            while (File2.hasNextLine())
            {
                ArrayList2.add(File2.next());
            }
        }
        catch (FileNotFoundException ex)
        {
            ex.printStackTrace();
        }
        for (String ArrayList : ArrayList1) 
        {
            System.out.println("File 1: " + ArrayList1);
        }
        for (String ArrayList : ArrayList2) 
        {
            System.out.println("File 2: " + ArrayList2);
        }

        if(ArrayList1.size()>ArrayList2.size())
        {
            for(int i=0; i<ArrayList1.size()-1; i++)
            {
                if(ArrayList1.get(i).equals(ArrayList2.get(i)))
                {
                    temp++;
                }
            }
        }
        if(ArrayList2.size()>ArrayList1.size())
        {
            for(int i=0; i<ArrayList2.size()-1; i++)
            {
                if(ArrayList2.get(i).equals(ArrayList1.get(i)))
                {
                    temp++;
                }
            }
        }
        if(temp == 0)
        System.out.println("The files are the same.");
        else
            System.out.println("There are " + temp + " differences between the files");

    }
}

【问题讨论】:

  • 您首先在代码中检查 ArrayList2.size() > ArrayList1.size() ,然后您正在操作从 0 到 ArrayList2.size() 长度的 for 循环。因为 ArrayList2 更大,所以您将找不到 ArrayList1 中 i 点的最后一个元素!我认为你的 for 循环应该从 0 到 ArrayList1.size() 因为那个更短
  • 如果一个列表比另一个大,你怎么能期望用相同的索引遍历它们呢?还有,读完文件为什么不关闭呢?
  • @AntonH 这不是问题所在。 for-condition 是i &lt; ArrayList1.size()-1,所以它会在i == ArrayList1.size()-2 之后停止,因为严格小于。正确的条件是i &lt; ArrayList1.size()实际 问题是 OP 使用了错误的限制:他应该在他的条件下使用两种尺寸中的 最小的。此外,他可能应该在他的 if 测试中使用大于或等于。

标签: java arraylist java.util.scanner indexoutofboundsexception


【解决方案1】:

这就是问题所在:

    if(ArrayList1.size()>ArrayList2.size())
    {
    //ArrayList1 is bigger!!!!

        for(int i=0; i<ArrayList1.size()-1; i++)
        {
            if(ArrayList1.get(i).equals(ArrayList2.get(i)))
            // ArrayList2 does not contain as many elements as ArrayList1
            {
                temp++;
            }
        }
    }

因此。您可以从 0 -> ArrayList.size() 开始循环,但请务必使用较短的列表作为循环的限制! :-)

【讨论】:

  • 没错,但-1 仍然是错误的。使用ArrayList2.size()-1 不会检查ArrayList2 中的最后一个元素。
  • 这是真的 :) 如果你想遍历整个数组,你需要从 0 -> Arraylist.size() 开始,就像我在代码之后已经提到的那样
【解决方案2】:

或者,您可以替换:

for(int i=0; i<ArrayList1.size()-1; i++)

与:

for (String s : ArrayList1)

这称为 for-each 循环,可用于更易读更简单的迭代。

【讨论】:

  • 在这种情况下,您将如何比较两个列表中的匹配元素?您需要比较每个元素的元素,因此您需要使用i 来索引两个列表。
【解决方案3】:

正如 Sara Seppola 已经提到的,您需要使用两个大小中的最小来比较两个列表中的元素。目前,您使用的是两者中最大的一个,保证您将超出较小列表的范围。

另外,您应该在循环限制中使用ArrayList1.size() 而不是ArrayList1.size()-1,因为当前循环条件中的严格小于检查导致i0 迭代到ArrayList1.size()-2 - 太短了。同样,索引越界不是-1引起的,而是因为条件中使用的大小不正确。

最后,您没有考虑列表大小相等的情况。目前,您的代码给出“文件相同”,因为当 ArrayList1.size() == ArrayList2.size() 时没有通过 if-test。

if(ArrayList1.size() >= ArrayList2.size())
{
    // Here, ArrayList1.size() >= ArrayList2.size()
    // Use the smallest size as limit so we stay in bounds for both
    // In this case, that's ArrayList2.size()
    // When the lists have equal length, both sizes could be used
    // as limit so it doesn't really matter whether you use
    // > or >= in the test of the above if-statement
    for(int i=0; i<ArrayList2.size(); i++)
    {
        if(ArrayList1.get(i).equals(ArrayList2.get(i)))
        {
            temp++;
        }
    }
}
else
{
    // Here, ArrayList1.size() < ArrayList2.size()
    // so use ArrayList1.size() as the limit
    for(int i=0; i<ArrayList2.size(); i++)
    {
        if(ArrayList2.get(i).equals(ArrayList1.get(i)))
        {
            temp++;
        }
    }
}

但您的代码中仍然存在错误:您只是在比较相应的元素。更大列表中的额外元素呢?这些也应该算作差异。

一个快速的解决方法是简单地减去两个大小以获得更大列表中额外元素的数量,并将其用作差异数量的初始值:

if(ArrayList1.size() >= ArrayList2.size())
{
    temp = ArrayList1.size() - ArrayList2.size();
    // [for loop]
}
else
{
    temp = ArrayList2.size() - ArrayList1.size();
    // [for loop]
}

当然,您仍然可以简化代码。您可以使用Math.min(ArrayList1.size(), ArrayList2.size()) 来获得两种尺寸中最小的一个并删除重复的循环。您也可以使用Math.abs(ArrayList1.size() - ArrayList2.size()) 来获取额外元素的数量,无论ArrayList1 还是ArrayList2 是最大的。我将把它作为练习留给读者。 ;-)

【讨论】:

  • 非常感谢大家!!!我能够理解所有内容并以适当的方式对其进行编码! :D
【解决方案4】:
if(ArrayList1.size()>ArrayList2.size())
{
    for(int i=0; i<ArrayList1.size()-1; i++)
    {
        if(ArrayList1.get(i).equals(ArrayList2.get(i)))
        {
            temp++;
        }
    }
}

在这里,您首先检查ArrayList1 是否有比ArrayList2 更多的项目,然后循环遍历更大的ArrayList1,在ArrayList1ArrayList2 上使用get(i)

因为ArrayList1 的项目比ArrayList2 多,最终您将get 来自ArrayList1 的索引X 的项目,而您不能从ArrayList2 获得get 的项目,因为ArrayList2 包含的项目更少。

示例:ArrayList1 有 10 个项目,ArrayList2 有 9 个项目。您输入 if 是因为 10 > 9。然后在 for 循环的最后一次迭代中您执行 ArrayList1.get(9) 这很好,因为它有 10 个项目并且这是第 10 个,但 ArrayList2.get(9) 将失败,因为它只有 9 个项目。 8 是您可以使用的最高索引。

第二个 if 有同样的问题,但反过来。

阻止错误发生的解决方法是

for(int i = 0; i < ArrayList2.size(); i++)
{
    ...

这可能不会执行您希望代码执行的操作,但错误会消失。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    相关资源
    最近更新 更多