Мне было просто любопытно знать - почему делает Arrays.equals (дважды [] [], дважды [] []) возвращают 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 и печатает "Равный". Метод только работает с единственными размерами? если так, есть ли что-то подобное для многомерных массивов в Java?
Используйте 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
предоставляет статический
метод equals(int[], int[])
.
System.out.println(
java.util.Arrays.equals(
new int[] {1,2},
new int[] {1,2}
)
); // prints "true"
int[]
is an instanceof Object
int[][][]
is an instanceof Object[]
int[][][]
is NOT an 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[]
int[] { 1 }
int[] { 2, 3 }
. Object[]
экземпляраint[]
экземпляраИз предыдущего пункта должно быть ясно, что это вызывает Arrays.equals(Object[], Object[])
перегрузку. Из API:
Возвращает
true
, если два указанных массиваобъектов
равны друг другу. Два массива считаютсяравными
, если оба массива содержат одинаковое количество элементов, и все соответствующие пары элементов в двух массивах равны. Два объекта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
.