2
public static int Obstacle[][] = {{1, 3}, {2, 2}};

public static boolean testerFunction(int j, int k) {
    int check[] = {j, k};
    if (Arrays.asList(Obstacle).contains(check)) {
        return true;
    }
    else {
        return false;
    }
}

I have this code.

It always returns false, despite check being equal to {1,3} or {2,2}

What is wrong with my code? How do you check if an array exists in an array of arrays in Java?

0

3 Answers 3

2

You are checking for reference equality rather than object equality. See below for object equality check using Arrays.equals.

int[] a1 = { 1, 2 };
int[] a2 = { 1, 2 };
System.out.println(a1 == a2); // false (two different instances)
System.out.println(Arrays.equals(a1, a2)); // true (instances are logically equal)

Also consider this test:

System.out.println(a1.equals(a2)); // false

For most objects in Java, this would be expected to return true since a1 and a2 are logically equal. However, Array does not override Object.equals(), so it falls back to the default check of reference equality ==. This is the underlying reason why your test if (Arrays.asList(Obstacle).contains(check)) does not pass. Collections.contains() uses Object.equals to compare the arrays. And this is why we must iterate through the outer array manually, as below:

public static int[][] obstacle = { { 1, 3 }, { 2, 2 } };

public static boolean testerFunction(int j, int k) {
  int[] check = { j, k };
  for (int[] a : obstacle) {
    if (Arrays.equals(a, check)) {
      return true;
    }
  }
  return false;
}

public static void main(String[] args) {
  System.out.println(testerFunction(1, 3)); // true
  System.out.println(testerFunction(2, 2)); // true
  System.out.println(testerFunction(0, 0)); // false
}
Sign up to request clarification or add additional context in comments.

8 Comments

Do you mean reference equality? because instance and object are exactly the same!
I explained what I meant, if the terms are ambiguous to you, and admittedly they can be. I will edit post it to "reference quality" because that is what the JLS uses, though a quick web search will show that "instance equality" is commonly used to represent the same thing, as is "value equality" used as a synonym for "object equality." If I got to redefine convention here, I think I would change the terms to "object equality" vs "object equivalence." Essentially you are asked "is this object the SAME object" vs "is this object an EQUIVALENT object."
Along those same lines, I'll bet if Object.equals() had been named as Object.isEquivalentTo() it might have made things slightly easier on newbies... though it is less readable on the other hand.
Arrays.equals(...) is not object equality, or anything really. It's a static utility method taking two arrays as inputs.
This answer is correct, but I think one more detail should be explained for the OP's benefit. The original code fails because although Collection#contains() compares elements using equals(...), arrays do not override equals(...). You could add this line to your first code example: System.out.println(a1.equals(a2)); // false (default equals method tests reference equality, not logical equality)
|
0

The problem with your code is that whilst the array elements may be equivalent, the enclosing arrays are not.

Consider the following example:

int[] a = {1, 2, 3}
int[] b = {1, 2, 3}

System.out.println(a == b); //Prints false

Whilst arrays a and b both contain elements 1, 2 and 3, they are functionally different arrays occupying different memory spaces.

The only way to achieve what you want is through manual looping, dereferencing and comparing to determine if elements are equal (or using built-in methods like Arrays.equals()).

An example solution would be:

public static boolean testerFunction(int... elems){
    for(int[] candidate : Obsticle){
        // Filter out null and mismatching length arrays.
        if(candidate == null || candidate.length != elems.length){
            continue;
        }

        // Check equivilence using Arrays.equals()
        if(Arrays.equals(candidate, elems)){
            return true;
        }
    }

    // No arrays matched, return false
    return false;
}

Comments

0

Just to pitch in on a Java 8 solution as well:

public boolean testerFunction(int[][] arr2d, int... ints) {
    return Arrays.stream(arr2d).anyMatch(arr -> Arrays.equals(arr, ints));
}

Note that the second parameter is a varargs array and it can obviously be changed to simply take two ints as in the OPs example.

The example uses Java 8 Streams and you can find a great tutorial on streams here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.