[java] Java에서 equals vs Arrays.equals

Java에서 배열을 비교할 때 다음 두 문 사이에 차이점이 있습니까?

Object[] array1, array2;
array1.equals(array2);
Arrays.equals(array1, array2);

그렇다면 그렇다면 무엇입니까?



답변

array1.equals(array2)와 동일합니다 array1 == array2. 즉 같은 배열입니다. @alf가 지적했듯이 대부분의 사람들이 기대하는 것은 아닙니다.

Arrays.equals(array1, array2) 배열의 내용을 비교합니다.


비슷하게 array.toString()유용하지 않을 수 있으므로 사용해야 Arrays.toString(array)합니다.


답변

그것은 악명 높은 문제입니다. .equals()배열이 심하게 손상되었으므로 사용하지 마십시오.

그것은 “누군가가 실제로 잘못한 것”과 같이 “파손 된”것이 아니라 정의 된 것과 보통 예상되는 것을하지 않는 것입니다. 그래서 순수 주의자들에게는 : 그것은 완벽하게 괜찮 습니다.

이제 예상되는 동작 equals은 데이터를 비교하는 것입니다. 기본 동작은 Object데이터가없는 것처럼 신원을 비교하는 것입니다 (순수 자의 경우 : 그렇습니다. equals서브 클래스에서 필요한 경우 구현한다고 가정 합니다. 배열에는 구현이 없으므로 사용하지 않아야합니다.

따라서 차이점은 예상대로Arrays.equals(array1, array2) 작동합니다 (예 : 내용 비교). 다시 구현으로 넘어 가서 정체성을 비교하므로 (순수 주의자 : 예 나는 알고 있습니다 ).array1.equals(array2)Object.equals==null

문제는 Arrays.equals(array1, array2)배열의 요소가 equals제대로 구현 되지 않으면 열심히 물릴 것 입니다. 나는 매우 순진한 진술이지만, 명백히 덜 중요한 경우가 있습니다 .2D 배열을 고려하십시오.

Java의 2D 배열은 배열의 배열이며 배열 equals은 깨지거나 원하는 경우 쓸모 Arrays.equals(array1, array2)가 없으므로 2D 배열에서 예상대로 작동하지 않습니다.

희망이 도움이됩니다.


답변

두 가지 방법의 구현을 살펴보고 깊이 이해하십시오.

array1.equals(array2);
/**
 * Indicates whether some other object is "equal to" this one.
 * <p>
 * The {@code equals} method implements an equivalence relation
 * on non-null object references:
 * <ul>
 * <li>It is <i>reflexive</i>: for any non-null reference value
 *     {@code x}, {@code x.equals(x)} should return
 *     {@code true}.
 * <li>It is <i>symmetric</i>: for any non-null reference values
 *     {@code x} and {@code y}, {@code x.equals(y)}
 *     should return {@code true} if and only if
 *     {@code y.equals(x)} returns {@code true}.
 * <li>It is <i>transitive</i>: for any non-null reference values
 *     {@code x}, {@code y}, and {@code z}, if
 *     {@code x.equals(y)} returns {@code true} and
 *     {@code y.equals(z)} returns {@code true}, then
 *     {@code x.equals(z)} should return {@code true}.
 * <li>It is <i>consistent</i>: for any non-null reference values
 *     {@code x} and {@code y}, multiple invocations of
 *     {@code x.equals(y)} consistently return {@code true}
 *     or consistently return {@code false}, provided no
 *     information used in {@code equals} comparisons on the
 *     objects is modified.
 * <li>For any non-null reference value {@code x},
 *     {@code x.equals(null)} should return {@code false}.
 * </ul>
 * <p>
 * The {@code equals} method for class {@code Object} implements
 * the most discriminating possible equivalence relation on objects;
 * that is, for any non-null reference values {@code x} and
 * {@code y}, this method returns {@code true} if and only
 * if {@code x} and {@code y} refer to the same object
 * ({@code x == y} has the value {@code true}).
 * <p>
 * Note that it is generally necessary to override the {@code hashCode}
 * method whenever this method is overridden, so as to maintain the
 * general contract for the {@code hashCode} method, which states
 * that equal objects must have equal hash codes.
 *
 * @param   obj   the reference object with which to compare.
 * @return  {@code true} if this object is the same as the obj
 *          argument; {@code false} otherwise.
 * @see     #hashCode()
 * @see     java.util.HashMap
 */
public boolean equals(Object obj) {
    return (this == obj);
}

동안:

Arrays.equals(array1, array2);
/**
 * Returns <tt>true</tt> if the two specified arrays of Objects are
 * <i>equal</i> to one another.  The two arrays are considered equal if
 * both arrays contain the same number of elements, and all corresponding
 * pairs of elements in the two arrays are equal.  Two objects <tt>e1</tt>
 * and <tt>e2</tt> are considered <i>equal</i> if <tt>(e1==null ? e2==null
 * : e1.equals(e2))</tt>.  In other words, the two arrays are equal if
 * they contain the same elements in the same order.  Also, two array
 * references are considered equal if both are <tt>null</tt>.<p>
 *
 * @param a one array to be tested for equality
 * @param a2 the other array to be tested for equality
 * @return <tt>true</tt> if the two arrays are equal
 */
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++) {
        Object o1 = a[i];
        Object o2 = a2[i];
        if (!(o1==null ? o2==null : o1.equals(o2)))
            return false;
    }

    return true;
}


답변

한숨. 70 년대에는 IBM 370 시스템의 “시스템 프로그래머”(sysadmin) 였고, 고용주는 IBM 사용자 그룹 SHARE의 구성원이었습니다. 누군가가 일부 CMS 명령의 예기치 않은 동작에 대해 APAR (버그 보고서)을 제출 한 경우가있을 수 있으며 IBM은 NOTABUG로 응답합니다.

SHARE는 BAD-Broken As Designed에 대한 카운터를 제시했습니다. 이것이 배열의 equals 구현에 적용될 수 있다고 생각합니다.

Object.equals 구현에는 아무런 문제가 없습니다. 개체에 데이터 멤버가 없으므로 비교할 것이 없습니다. 두 개의 “Object”는 실제로 동일한 Object (내부적으로 동일한 주소 및 길이) 인 경우에만 동일합니다.

그러나 해당 논리는 배열에는 적용되지 않습니다. 배열에는 데이터가 있으며 데이터를 비교하기 위해 (등을 통해) 비교를 기대합니다. 이상적으로 Arrays.deepEquals와 같은 방식이지만 최소한 Arrays.equals와 같은 방식 (요소의 얕은 비교).

따라서 문제는 배열 (내장 객체)이 Object.equals를 재정의하지 않는다는 것입니다. (명명 된 클래스로) 문자열 않습니다 오버라이드 Object.equals을 당신이 기대하는 결과를 제공합니다.

주어진 다른 대답은 정확합니다. […]. equals ([….])는 단순히 내용이 아닌 포인터를 비교합니다. 아마 언젠가 누군가가 이것을 고칠 것입니다. 아니면 어쩌면 : […]. equals가 실제로 요소를 비교하면 몇 개의 기존 프로그램이 중단됩니까? 많지는 않지만 나는 0보다 큰 것으로 생각합니다.


답변

배열 equals()Object 따라서 및 자체에 대한 배열을 비교하는 경우에만 true를 돌려주는 비교할 수 있습니다.

반면에 Arrays.equals 배열의 요소를 비교합니다.

이 스 니펫은 차이점을 설명합니다.

Object o1 = new Object();
Object o2 = new Object();
Object[] a1 = { o1, o2 };
Object[] a2 = { o1, o2 };
System.out.println(a1.equals(a2)); // prints false
System.out.println(Arrays.equals(a1, a2)); // prints true

도 참조하십시오 Arrays.equals(). 관심있는 또 다른 정적 방법은 다음과 같습니다 Arrays.deepEquals()..


답변

그만큼 Arrays.equals(array1, array2):

두 배열에 같은 수의 요소가 포함되어 있고 두 배열의 모든 해당 요소 쌍이 같은지 확인하십시오.

그만큼 array1.equals(array2):

객체를 다른 객체와 비교하고 두 객체의 참조가 Object.equals()


답변

equals()배열이에서 상속 Object는 arrrays의 내용을 보지 않도록, 그것은 각 배열 자체에 동일 간주합니다.

Arrays.equals()방법은 않습니다 배열 ‘의 내용을 비교합니다. 모든 기본 유형에 대한 과부하가 있으며 객체에 대한 유형은 객체 자체의 equals()메소드를 사용합니다 .