Использование 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
.