Matt
Matt

Reputation: 3912

Comparing equality of 2 ArrayList<int[]> with equals()

I have two ArrayLists which are ArrayList<int[]>. I want to see if they are identical. By identical I mean the same length, same content and in the same order. I am comparing the ArrayLists as so:

public boolean isWon() {

    if(getAllBtnCoords().equals(getAllTVCoords())) {
        Toast.makeText(getApplicationContext(), "YOU WON!", Toast.LENGTH_LONG).show();
        return true;
    } else {
        Toast.makeText(getApplicationContext(), "NOT YET...", Toast.LENGTH_LONG).show();
        return false;
    }
}

I have even gone so far as create an ArrayList<int[]>, then create a new variable and just set it equal to the already created ArrayList<int[]> so that I am 100% sure they are the same. I then run the isWon() method and it always returns false.

What am I doing incorrectly? Am I using the wrong function of equals() to compare?

Upvotes: 0

Views: 2443

Answers (4)

Josef Raška
Josef Raška

Reputation: 1301

Equals in ArrayList internally call equals on its elements. Int array implementation is just comparing references which are not same so the correct comparing function would be.

public static boolean intArraysEquals(List<int[]> listOne, List<int[]> listTwo)
{
    if(listOne.size() != listTwo.size())
        return false;

    for(int i = 0, size = listOne.size(); i < size; i++)
    {
        int[] firstArray = listOne.get(i);
        int[] secondArray = listTwo.get(i);

        if(!Arrays.equals(firstArray, secondArray))
        {
            return false;
        }
    }

    return true;
}

than your isWon() function could look like

public boolean isWon() {

    if(intArraysEquals(getAllBtnCoords(), getAllTVCoords())) {
        Toast.makeText(getApplicationContext(), "YOU WON!", Toast.LENGTH_LONG).show();
        return true;
    } else {
        Toast.makeText(getApplicationContext(), "NOT YET...", Toast.LENGTH_LONG).show();
        return false;
    }
}

Upvotes: 1

Raffaele Rossi
Raffaele Rossi

Reputation: 1109

On quick solution would be:

  • Define your own comparison method whi which takes the to ArrayList as inputs
  • Check none of them is null
  • Check both have the same size
  • One by one take the two arrays
  • Check these to have the same length
  • Then iterates through all of them and check to be equal
  • If any of the previous is not true, return false, otherwise you got a match

Something like:

private boolean areArrayEqual(ArrayList<int[]> a, ArrayList<int[]> b) {
    if (a == null) return false;
    if (b == null) return false;
    if (a.size() != b.size()) return false;
    for (int i = 0; i < a.size(); i++) {
        int x[] = a.get(i);
        int y[] = b.get(i);
        if (x.length != y.length) return false;
        for (int j = 0; j < x.length; j++) {
            if (x[j] != y[j]) return false;
        }
    }
    return true;
}

Upvotes: 1

Bart Enkelaar
Bart Enkelaar

Reputation: 694

I think your problem lies in that the equals method for arrays is basically not implemented, it only matches on object equality. So as long as the coordinate arrays in the two lists are not the exact same objects it will return false.

For example, this piece of code prints false:

public static void main(String[] args) {
    int[] a = {1, 2};
    int[] b = {1, 2};
    System.err.println(a.equals(b));
}

I would advise you to replace the usage of int arrays by Point or Coordinate objects with a properly implemented equals (and hashcode) function. (Perhaps a lombok @Data object!).

Upvotes: 1

ajb
ajb

Reputation: 31689

An ArrayList<int[]> is a list of arrays of integers. So it looks like you're trying to compare a two-dimensional array, more or less. When you use equals on an ArrayList or any other List, it compares each element of the List using the equals function of the element type.

The problem is that arrays such as int[] don't have a special equals function. Arrays are objects, and the default equals for objects compares the references to see if they're equal. So using .equals on the ArrayList will return true if the elements of the ArrayList, which are int[], are all the same reference. It will not check the elements of the int[] arrays.

Either you'll need to do this yourself with a loop; or make your type an ArrayList<ArrayList<Integer>>, which would make equals work fine.

Upvotes: 2

Related Questions