Ответ 1
Используйте deepEquals(Object[], Object[])
.
Возвращает
true
, если два указанных массива глубоко равны друг другу.
Так как a int[]
является instanceof Object
, a 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
- An
int[]
являетсяinstanceof Object
- An
int[][]
- этоinstanceof Object[]
-
int[][]
НЕ ainstanceof 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 }
.
- Элемент с индексом 0 является
- Есть два экземпляра
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 "[[[email protected], [[email protected]]"
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
.