Question

Here is my code to distinguish the differences between two txt files. The only problem is i get an out of bounds exception if i dont subtract 1 from the arrayList, so right now it is not running for all of the elements, how do i fix this?

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");

    }
}
Was it helpful?

Solution 3

As Sara Seppola already mentioned, you need to use the smallest of the two sizes to compare the elements in the two lists. Currently, you're using the biggest of the two, which guarantees that you'll go out of bounds on the smaller list.

Also, you should be using ArrayList1.size() and not ArrayList1.size()-1 in your loop limits, as the strictly less than check in your loop condition currently causes i to iterate from 0 to ArrayList1.size()-2 - which is one too short. Again, the index-out-of-bounds is not caused by the -1, but rather because of the incorrect size used in the condition.

Finally, you're not accounting for the case where the lists have equal sizes. Currently, your code gives "The files are the same" since there's not if-test which passes when ArrayList1.size() == ArrayList2.size().

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++;
        }
    }
}

There's still an error in your code though: you're only comparing corresponding elements. What about the extra elements from the larger list? Those should be counted as differences as well.

A quick fix would be to simply subtract the two sizes to get the number of extra elements in the bigger list, and use that as initial value for the number of difference:

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

Of course, you could still simplify your code. You could use Math.min(ArrayList1.size(), ArrayList2.size()) to get the smallest of the two sizes and remove the duplicated loop. You could also use Math.abs(ArrayList1.size() - ArrayList2.size()) to get the number of extra elements, regardless whether ArrayList1 or ArrayList2 is the largest. I'll leave that as an exercise for the reader. ;-)

OTHER TIPS

This is the problem:

    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++;
            }
        }
    }

therefore. You can have your loop from 0 -> ArrayList.size() but be sure to use the shorter list as the limit for the loop! :-)

Alternatively, you can replace:

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

With:

for (String s : ArrayList1)

This is called a for-each loop and can be used for more readable simpler iteration.

if(ArrayList1.size()>ArrayList2.size())
{
    for(int i=0; i<ArrayList1.size()-1; i++)
    {
        if(ArrayList1.get(i).equals(ArrayList2.get(i)))
        {
            temp++;
        }
    }
}

Here you first check if ArrayList1 has more items than ArrayList2, and then you loop over the bigger ArrayList1, using get(i) on ArrayList1 as well as ArrayList2.

Because ArrayList1 has more items than ArrayList2, eventually you will get an item from at index X from ArrayList1 that you cannot get from ArrayList2 because ArrayList2 contains less items.

Example: ArrayList1 has 10 items and ArrayList2 has 9 items. You enter the if because 10 > 9. Then at the last iteration in the for loop you do ArrayList1.get(9) which is fine because it has 10 items and this gets the 10th, but ArrayList2.get(9) will fail because it has only 9 items. 8 is the highest index you can work with.

The second if has the same problem, but the other way around.

A fix to stop the error from occurring would be to

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

This might not do what you want your code to do, but the error will be gone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top