В Java 7 равно () и deepEquals()
Описание метода говорит:
Возвращает true, если аргументы глубоко равны друг другу, и false в противном случае... Равенство определяется с помощью метода equals первого аргумента.
Что (для меня) говорит о том, что объекты глубоко равны, если каждый объект, на который они ссылаются, также равен с помощью метода equals(). И все объекты, на которые они ссылаются, также равны. А также..
Так.. equality is determined by using the equals method of the first argument.
Чем это отличается от .equals()
? Предполагая, что мы описываем равные соответственно, где объекты равны другому объекту, если каждое поле объекта равно ему.
Можете ли вы привести пример, иллюстрирующий разницу между Objects.deepEquals()
а также Objects.equals()
?
5 ответов
Если хотя бы один из аргументов deepEquals
метод не является массивом, то Objects.deepEquals
а также Objects.equals
такие же.
String[] firstArray = {"a", "b", "c"};
String[] secondArray = {"a", "b", "c"};
System.out.println("Are they equal 1 ? " + firstArray.equals(secondArray) );
System.out.println("Are they equal 2 ? " + Objects.equals(firstArray, secondArray) );
System.out.println("Are they deepEqual 1? " + Arrays.deepEquals(firstArray, secondArray) );
System.out.println("Are they deepEqual 2? " + Objects.deepEquals(firstArray, secondArray) );
вернусь
Are they equal 1 ? false
Are they equal 2 ? false
Are they deepEqual 1? true
Are they deepEqual 2? true
Как получилось "неглубоко" equals
методы возврата false
? Это связано с тем, что в Java для массивов равенство определяется идентичностью объекта. В этом примере firstArray
а также secondArray
являются различными объектами.
дела String[] secondArray = firstArray
вместо этого поэтому вернется true
для всех четырех тестов.
Пример:
import java.util.Arrays;
import java.util.Objects;
public class Main {
public static void main(String[] args) {
Integer[] x = { 1, 2 };
Integer[] y = { 1, 2 };
System.out.println(Objects.equals(x, y)); // false
System.out.println(Objects.deepEquals(x, y)); // true
System.out.println(Arrays.equals(x, y)); // true
System.out.println(Arrays.deepEquals(x, y)); // true
System.out.println();
int[][] a = { { 1, 2 }, { 3, 4 } };
int[][] b = { { 1, 2 }, { 3, 4 } };
System.out.println(Objects.equals(a, b)); // false
System.out.println(Objects.deepEquals(a, b)); // true
System.out.println(Arrays.equals(a, b)); // false
System.out.println(Arrays.deepEquals(a, b)); // true
}
}
Документация и декомпилированный код:
Objects#equals(Object a, Object b)
: возвращает true, если аргументы равны друг другу, и false в противном случае. Следовательно, если оба аргумента равны нулю, возвращается значение true, а если ровно один аргумент равен нулю, возвращается значение false. В противном случае равенство определяется с помощью метода equals первого аргумента.
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
Objects#deepEquals(Object a, Object b)
: возвращает true, если аргументы глубоко равны друг другу, и false в противном случае. Два нулевых значения глубоко равны. Если оба аргумента являются массивами, алгоритм в Arrays.deepEquals используется для определения равенства. В противном случае равенство определяется с помощью метода equals первого аргумента.
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}
Arrays#equals(Object[] a, Object[] a2)
: возвращает true, если два указанных массива объектов равны друг другу. Два массива считаются равными, если оба массива содержат одинаковое количество элементов и все соответствующие пары элементов в двух массивах равны.
public static boolean equals(Object[] a, Object[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++) {
if (!Objects.equals(a[i], a2[i]))
return false;
}
return true;
}
Arrays#deepEquals(Object[] a1, Object[] a2)
: возвращает true, если два указанных массива глубоко равны друг другу. в отличие от
equals(Object[],Object[])
этот метод подходит для использования с вложенными массивами произвольной глубины .
public static boolean deepEquals(Object[] a1, Object[] a2) {
if (a1 == a2)
return true;
if (a1 == null || a2==null)
return false;
int length = a1.length;
if (a2.length != length)
return false;
for (int i = 0; i < length; i++) {
Object e1 = a1[i];
Object e2 = a2[i];
if (e1 == e2)
continue;
if (e1 == null)
return false;
// Figure out whether the two elements are equal
boolean eq = deepEquals0(e1, e2);
if (!eq)
return false;
}
return true;
}
static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}
deepEquals() используется с вложенными массивами произвольной глубины.
equals () используется с простыми примитивными типами данных.
Например:
public class TwoDArray {
public static void main(String args[]) {
int a[][] = new int[2][2];
int b[][] = new int[2][2];
for(int i=0;i<2;i++)
for(int j=0;j<2;j++) {
a[i][j] = i+j;
b[i][j] = i+j;
}
System.out.println(Arrays.deepEquals(a,b));//return true
System.out.println(Arrays.equals(a, b));//return false
}
}
Прилагаю очень хороший пример, который я нашел на javarevisited.blogspot.in
public class ArrayCompareTest {
public static void main(String args[]) {
//comparing primitive int arrays in Java
int[] i1 = new int[] {1,2,3,4};
int[] i2 = new int[] {1,2,3,4};
int[] i3 = new int[] {0,2,3,4};
//Arrays.equals() compare Array and return true if both array are equal
//i..e either both of them are null or they are identical in length, and each pair
//match each other e.g. i[0]=i2[0], i[1]=i2[1] and so on
//i1 and i2 should be equal as both contains same elements
boolean result = Arrays.equals(i1, i2);
System.out.println("Comparing int array i1: " + Arrays.toString(i1)
+ " and i1: " + Arrays.toString(i2));
System.out.println("Does array i1 and i2 are equal : " + result);
//array ii2 and i3 are not equals as only length is same, first pair is not same
result = Arrays.equals(i2, i3);
System.out.println("Comparing int array i2: " + Arrays.toString(i2)
+ " and i3: " + Arrays.toString(i3));
System.out.println("Does array i2 and i3 are equal : " + result);
//comparing floating point or double arrays in Java
double[] d1 = new double[] {1.5, 2.4, 3.2, 4,1};
double[] d2 = new double[] {1.5, 2.4, 3.2, 4,1};
double[] d3 = new double[] {0.0, 2.4, 3.2, 4,1};
//Comparing two floating-point arrays using Arrays.equals() in Java
//double array d1 and d2 should be equal - length same, each index matches
result = Arrays.equals(d1, d2);
System.out.println("Comparing double array d1: " + Arrays.toString(d1)
+ " and d2: " + Arrays.toString(d2));
System.out.println("Does double array d1 and d2 are equal : " + result);
//double array d2 and d3 is not equal - length same, first pair does not match
result = Arrays.equals(d2, d3);
System.out.println("Comparing double array d2: " + Arrays.toString(d2)
+ " and d3: " + Arrays.toString(d3));
System.out.println("Does double array d2 and d3 are same : " + result);
//comparing Object array, here we will use String array
String[] s1 = new String[]{"One", "Two", "Three"};
String[] s2 = new String[]{"One", "Two", "Three"};
String[] s3 = new String[]{"zero", "Two", "Three"};
//String array s1 and s2 is equal - length same, each pair matches
result = Arrays.equals(s1, s2);
System.out.println("Comparing two String array s1: " + Arrays.toString(s1)
+ " and s2: " + Arrays.toString(s2));
System.out.println("Are both String array s1 and s2 are equal : " + result);
//String array s2 and s3 is not equal - length same, first pair different
result = Arrays.equals(d2, d3);
System.out.println("Comparing two String array s2: " + Arrays.toString(s2)
+ " and s3: " + Arrays.toString(s3));
System.out.println("Are both String array s2 and s3 are equal : " + result);
//Comparing nested arrays with equals and deepEquals method
//Arrays.equals() method does not compare recursively,
//while deepEquals() compare recursively
//if any element inside Array is type of Array itself,
//as here second element is String array
Object[] o1 = new Object[]{"one", new String[]{"two"}};
Object[] o2 = new Object[]{"one", new String[]{"two"}};
System.out.println("Object array o1: " + Arrays.toString(o1) + " and o2: "
+ Arrays.toString(o2));
System.out.println("Comparing Object Array o1 and o2 with Arrays.equals : "
+ Arrays.equals(o1, o2));
System.out.println("Comparing Object Array o1 and o2 with Arrays.deepEquals : "
+ Arrays.deepEquals(o1, o2));
}
}
Вывод: Сравнение массива int i1: [1, 2, 3, 4] и i1: [1, 2, 3, 4] Одинаковы ли массивы i1 и i2: true
Сравнение массива int i2: [1, 2, 3, 4] и i3: [0, 2, 3, 4] Одинаковы ли массивы i2 и i3: false
Сравнение двойного массива d1: [1.5, 2.4, 3.2, 4.0, 1.0] и d2: [1.5, 2.4, 3.2, 4.0, 1.0] Одинаковы ли двойные массивы d1 и d2: true
Сравнение двойного массива d2: [1.5, 2.4, 3.2, 4.0, 1.0] и d3: [0.0, 2.4, 3.2, 4.0, 1.0] Одинаковы ли двойные массивы d2 и d3: false
Сравнивая два строковых массива s1: [One, Two, Three] и s2: [One, Two, Three] Оба строковых массива s1 и s2 равны: true
Сравнение двух строковых массивов s2: [One, Two, Three] и s3: [zero, Two, Three] Оба строковых массива s2 и s3 равны: false
Массив объектов o1: [one, [Ljava.lang.String;@19821f] и o2: [one, [Ljava.lang.String;@addbf1] Сравнение массива объектов o1 и o2 с Arrays.equals: false Сравнение массива объектов o1 и o2 с Arrays.deepEquals: правда