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?
source to share
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
source to share
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:
source to share
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 .
source to share
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)
source to share