Java Arrays.equals () возвращает false для двумерных массивов - PullRequest
38 голосов
/ 27 апреля 2010

Мне было просто интересно узнать - почему Arrays.equals (double [] [], double [] []) возвращает false? когда на самом деле массивы имеют одинаковое количество элементов и каждый элемент одинаков?

Например, я выполнил следующий тест.

double[][] a,  b;
int size =5;

a=new double[size][size];
b=new double[size][size];

for( int i = 0; i < size; i++ )
    for( int j = 0; j < size; j++ ) {
        a[i][j]=1.0;
        b[i][j]=1.0;
    }

if(Arrays.equals(a, b))
    System.out.println("Equal");
else
    System.out.println("Not-equal");

Возвращает false и печатает «Не равно».

с другой стороны, если у меня есть что-то вроде этого:

double[] a,  b;
int size =5;

a=new double[size];
b=new double[size];

for( int i = 0; i < size; i++ ){
    a[i]=1.0;
    b[i]=1.0;
} 

if(Arrays.equals(a, b))
    System.out.println("Equal");
else
    System.out.println("Not-equal");

возвращает true и печатает "Equal". Метод работает только с отдельными измерениями? если да, то есть ли что-то подобное для многомерных массивов в Java?

Ответы [ 2 ]

109 голосов
/ 27 апреля 2010

Использование deepEquals(Object[], Object[]).

Возвращает true, если два указанных массива глубоко равны друг другу.

Поскольку int[] является instanceof Object, int[][] является instanceof Object[].


Что касается , почему Arrays.equals не "работает" для двумерных массивов, это можно объяснить шаг за шагом следующим образом:

Для массивов equals определяется с точки зрения идентификации объекта

System.out.println(
    (new int[] {1,2}).equals(new int[] {1,2})
); // prints "false"

Это потому, что массивы наследуют свои equals от своего общего суперкласса, Object.

Часто нам действительно нужно равенство значений для массивов, поэтому java.util.Arrays предоставляет static служебный метод equals(int[], int[]).

System.out.println(
    java.util.Arrays.equals(
        new int[] {1,2},
        new int[] {1,2}
    )
); // prints "true"

Массив массивов в Java

  • int[] является instanceof Object
  • int[][] является instanceof Object[]
  • int[][] - НЕ instanceof int[]

У Java на самом деле нет двухмерных массивов. Это даже не имеет многомерных массивов. У Java есть массив массивов.

java.util.Arrays.equals "мелкий"

Теперь рассмотрим этот фрагмент:

System.out.println(
    java.util.Arrays.equals(
        new int[][] {
            { 1 },
            { 2, 3 },
        },
        new int[][] {
            { 1 },
            { 2, 3 },
        }
    )
); // prints "false"

Вот факты:

  • Каждый аргумент является Object[]
    • Элемент с индексом 0 является int[] { 1 }
    • Элементом с индексом 1 является int[] { 2, 3 }.
  • Существует два Object[] экземпляра
  • Существует четыре int[] экземпляра

Из предыдущего пункта должно быть ясно, что это вызывает перегрузку Arrays.equals(Object[], Object[]). Из API:

Возвращает true, если два указанных массива Objects равны друг другу. Два массива считаются equal, если оба массива содержат одинаковое количество элементов, и все соответствующие пары элементов в двух массивах равны. Два объекта e1 и e2 считаются равными, если (e1==null ? e2==null : e1.equals(e2)).

Теперь должно быть понятно, почему вышеприведенный фрагмент печатает "false"; это потому, что элементы Object[] массивов не равны по вышеприведенному определению (так как int[] имеет equals, определенный идентификатором объекта).

java.util.Arrays.deepEquals "глубоко"

Напротив, вот что делает Arrays.deepEquals(Object[], Object[]):

Возвращает true, если два указанных массива глубоко равны друг другу. В отличие от метода equals(Object[],Object[]), этот метод подходит для использования с вложенными массивами произвольной глубины.

System.out.println(
    java.util.Arrays.deepEquals(
        new int[][] {
            { 1 },
            { 2, 3 },
        },
        new int[][] {
            { 1 },
            { 2, 3 },
        }
    )
); // prints "true"

Вкл Arrays.toString и Arrays.deepToString

Стоит отметить аналогию между этими двумя методами и тем, что мы уже обсуждали в отношении вложенных массивов.

System.out.println(
    java.util.Arrays.toString(
        new int[][] {
            { 1 },
            { 2, 3 },
        }
    )
); // prints "[[I@187aeca, [I@e48e1b]"

System.out.println(
    java.util.Arrays.deepToString(
        new int[][] {
            { 1 },
            { 2, 3 },
        }
    )
); // prints "[[1], [2, 3]]"

Опять же, рассуждения аналогичны: Arrays.toString(Object[]) обрабатывает каждый элемент как Object и просто вызывает его метод toString(). Массивы наследуют toString() от своего общего суперкласса Object.

Если вы хотите, чтобы java.util.Arrays рассматривал вложенные массивы, вам нужно использовать deepToString, так же, как вам нужно использовать deepEquals.

0 голосов
/ 09 апреля 2013

Java фактически не имеет многомерных массивов. Вместо этого он имеет только одномерный массив, и многомерные массивы будут массивами этих 1d-массивов. String.equals () может выполняться только для базовых одиночных блочных массивов, и, следовательно, он не работает для многомерных массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...