When using ArrayList <int [] []> how do I know if an item is in the list?

The use public boolean contains(Object o)

in the ArrayList library does not work in this case. Consider

ArrayList<int[][]> test = new ArrayList<>();

int[][] one = {
    {1,2,3},
    {4,5,6}
};
int[][] two = {
    {1,2,3},
    {4,5,6}
};
int[][] three = {
    {9,7,5},
    {1,2,4},
    {5,6,7}
};

test.add(one);
System.out.println(test.contains(one));
System.out.println(test.contains(two));
System.out.println(test.contains(three));

      

The above code returns

true
false
false

      

Is there a way to check for equality between them and make sure there are no duplicate values โ€‹โ€‹in the list?

+3


source to share


4 answers


The simplest approach I know is to extract it into a method using Arrays.deepEquals(Object[], Object[])

something like -

public static boolean contains(List<int[][]> al, int[][] toFind) {
    for (int[][] arr : al) {
        if (Arrays.deepEquals(arr, toFind)) {
            return true;
        }
    }
    return false;
}

      

Then you can check it like



public static void main(String[] args) {
    ArrayList<int[][]> test = new ArrayList<int[][]>();
    int[][] one = { { 1, 2, 3 }, { 4, 5, 6 } };
    int[][] two = { { 1, 2, 3 }, { 4, 5, 6 } };
    int[][] three = { { 9, 7, 5 }, { 1, 2, 4 }, { 5, 6, 7 } };
    test.add(one);
    if (contains(test, two)) {
        System.out.println("Found two");
    }
}

      

Output

Found two

      

+3


source


One solution would be to concatenate the arrays into a class that provides an appropriate implementation equals

.

class SquareArray {
    private int[][] array;

    public SquareArray(int[][] array) {
        this.array = array;
    }

    public int[][] getArray() {
        return array;
    }

    @Override
    public boolean equals(Object o) {
        return (o instanceof SquareArray) && 
               Arrays.deepEquals(array, ((SquareArray)o).array);
    }

    @Override
    public int hashCode() {
        return Arrays.deepHashCode(array);
    }

    @Override
    public String toString() {
        return Arrays.deepToString(array);
    }
}

      

You should now use List<SquareArray>

; eg:

int[][] a = {{1,2,3}, {4,5,6}};
int[][] b = {{1,2},{3,4},{5,6}};
int[][] c = {{1,2,3}, {4,5,6}};

SquareArray x = new SquareArray(a);
SquareArray y = new SquareArray(b);
SquareArray z = new SquareArray(c);

List<SquareArray> list = new ArrayList<>();
list.add(x);
System.out.println(list.contains(x));
System.out.println(list.contains(y));
System.out.println(list.contains(z));

      



true
false
true

Reference:

+3


source


I would like to suggest another solution using Java 8 streams and predicates:

The method Stream#anyMatch

can be used to check if a given list contains a specific element. The required predicate can be constructed succinctly using Arrays#deepEquals

:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class GenericContainsTest
{
    public static void main(String[] args)
    {
        List<int[][]> list = new ArrayList<int[][]>();
        int[][] one =
        { { 1, 2, 3 },
          { 4, 5, 6 } };
        int[][] two =
        { { 1, 2, 3 },
          { 4, 5, 6 } };
        list.add(one);
        if (list.stream().anyMatch(e->Arrays.deepEquals(e, two)))
        {
            System.out.println("Found two");
        }
    }
}

      


However, you mentioned that your intention is to ...

... make sure there are no duplicate values โ€‹โ€‹in the list

In this case, you should at least consider using List

, but Set

- in particular, a Set<SquareArray>

using a class SquareArray

that arashajii suggested in its response .

+2


source


contains

the method uses a method equals(e)

and when you use equals on array it is the same as when used ==

, so you are checking for reference equality, not content. To check if two arrays are equal, you should use or for nested arrays.Arrays.equals

(array1, array2)

Arrays.deepEquals

(nestedArray1, nestedArray2)

0


source







All Articles