단팥빵
219
2017-09-22 00:47:43
4
2923

Java Arrays 관련 질문입니다.


안녕하세요. 자바를 너무 대충 배운 것 같아서 다시 복습하며 배우고 있는 학생입니다.

제가 알기로는 equals는 메소드로 객체안의 내용을 비교하는 것이고, ==은 연산자로 객체의 주소를 비교하는 것으로 알고 있습니다.

이 부분은 hashCode()를 사용해서 주소 값도 확인해 봤구요...

문제는 Arrays클래스 입니다. 배열에 대해 알아보다가 Arrays라는 좋은 클래스가 존재한단 것을 알게 되었습니다.

하지만 헷갈리는 부분이 있습니다.

첫번째가, Arrays.equals(array1, array2) 와 Arrays.deepEquals(array1, array2)의 차이 입니다.

구글을 검색해보니 대다수의 분들이 깊게 비교해보았냐의 차이라고 적어 두셨더라구요...

두번째는 copyOf에 대한 내용입니다.

그래서 한 예제를 직접 실행해 보았습니다.

import java.util.Arrays;
 
public class EqualsExam {
    public static void main(String[] args) {
        int[][] origin = { {13}, {57} };
        
        System.out.println("[얕은 복제 후 비교]");
        int[][] clone1 = Arrays.copyOf(origin, origin.length);
        System.out.println("배열 번지 비교: " + origin.equals(clone1));
        System.out.println("1차 배열 항목값 비교: " + Arrays.equals(origin, clone1));
        System.out.println("중첩 배열 항목값 비교: " + Arrays.deepEquals(origin, clone1));
        
        System.out.println("\n[깊은 복제 후 비교]");
        int[][] clone2 = Arrays.copyOf(origin, origin.length);
        clone2[0= Arrays.copyOf(origin[0], origin[0].length);
        clone2[1= Arrays.copyOf(origin[1], origin[1].length);
        
        System.out.println("배열 번지 비교: " + origin.equals(clone2));
        System.out.println("1차 배열 항목값 비교: " + Arrays.equals(origin, clone2));
        System.out.println("중첩 배열 항목값 비교: " + Arrays.deepEquals(origin, clone2));
        
    }
}


출처: http://palpit.tistory.com/902 [palpit's log-b]



위의 결과로서는

false, true, true / false, false, true가 나옵니다...

origin과 clone1에 들어 있는 내용은 같은 것으로 알고있는데 왜 equals에서 false가 나오고 Arrays.equals에서 true가 나올까요?

또, origin과 clone2에서 Arrays.equals가 false가 나온 이유는 무엇일까요?  

clone2를 출력해보면 { {1,3}, {5,7} }로 저장되어 있다고 생각합니다. 위에서는 true였는데 왜 false일까요... 

deepEquals는 왜 계속 true일까요??? 정말 중첩된 배열이 하나라도 있는지 없는지 검사하는 것일까요? 그렇다면 {1} 과 {{1},{2}}도 true인가요.......


선배님들 도움이 필요합니다ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

선배님들의 지식을 저에게 알려주세요ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

이런 간단한 문제도 이해 못하고 있는 제가 부끄럽지만, 하나라도 확실하게 알고 넘어가고 싶습니다.

다른 친구들보다는 늦을 수 있지만, 기본만은 확실히 알고 가고 싶습니다.

존경하는 선배님들 초보자가 이해할 수 있는 명쾌한 답변 기다리겠습니다.

읽어주셔서 감사합니다!!!

모두들 화이팅!!!!!!!!!!!!!!!!!!!!

0
  • 답변 4

  • Kunie
    570
    2017-09-22 08:42:30

    배열의 equals() 는 Object 의 equals를 호출합니다. Object 의 equals 의 내부 연산은 this == target 이구요.

    Arrays.eqauls() 는 2차원 배열 두개를 파라미터로 넘기면 2차원 배열의 원소들(1차원 배열들)의 번지를 비교합니다. 이 때 원소들이 다시 배열일 것을 감안하지 않습니다.

    하지만 Arrays.deepEquals() 는 2차원 배열을 넘기더라도 다시 내부에서 원소들이 배열일 것을 감안하여 비교합니다. (배열이면 계속해서 deepEquals 를 재귀합니다.)

  • 단팥빵
    219
    2017-09-22 11:19:42

    감사합니다!!!!

    제가 이해한게 맞을까요?

    배열은 value라기 보다는 주소의 집합으로 이루어져 있고 이것은 equals로 비교할 수 없어서 배열의 equals는 내부 저장된 값과 상관없이 주소가 동일한지 비교하는 것?? 아니면 저장된 값이 주소 값??ㅠㅠㅠㅠ


    Arrays.equals()는 1차원 배열들의 번지를 비교 하는 것이고, Arrays.deepEquals()는 번지와 상관없이 배열임을 생각해서 원소 값들을 비교하는 것입니다.

    copyOf의 경우 clone1은 origin을 복사했으므로 origin과 clone1의 주소 값은 다르지만 (그래서 equals는 false) 내부 1차원 배열들의 번지는 동일하므로 true

    origin과 clone2의 경우는 1차원 배열들을 복사했으므로, 1차원 배열들의 번지는 다르므로 false


    즉, 1차원 배열일 때는 원소를 복사 / 2차원 배열일 때는 1차원 배열을 복사!

    제가 이해한게 맞는지 모르겠습니다.ㅠㅠㅠㅠㅠㅠㅠㅠ 혹시 틀린 점이 있다면 지적해 주시면 감사하겠습니다!!! 



  • Kunie
    570
    2017-09-22 12:40:04
    public static boolean equals(int[] a, int[] 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 (a[i] != a2[i])
                return false;
    
        return true;
    }

    실제로 구현되어있는 Arrays.equals(int[], int[]) 메소드 입니다.

    파라미터로 1차원 배열을 넘기도록 되어있는데,

    파라미터가 2차원 배열이었을 경우 어떻게 비교하게 될지 살펴보세요.

  • 단팥빵
    219
    2017-09-22 20:14:38

    감사합니다!!!!

  • 로그인을 하시면 답변을 등록할 수 있습니다.