본문 바로가기

etc.

[Java] 얕은 복사와 비교, 깊은 복사와 비교 (Objects, Arrays 클래스)

반응형

본문에 앞서, ==연산자equals() 메소드의 차이점을 짚고 가자

 

==연산자는 피연산자가 값과 주소가 같은지 검사한다

 

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");

System.out.println(str1 == str2);    //true
System.out.println(str1 == str3);    //false

 

그러나 equals() 메소드는 피연산자의 내용(값) 같은지를 검사한다

 

String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");

System.out.println(str1.equals(str2));    //true
System.out.println(str1.equals(str3));    //true

 


 

얕은 복사

데이터를 복사하는데, 복사 객체는 원본 객체와 같은 메모리 주소를 참조한다

 

흔히

int a = 1;
int b = a;    //얕은 복사

와 같이 대입을 하여 선언할 때 얕은 복사가 일어난다

 

하지만 이렇게 되면, 두 변수는 같은 주소의 값을 참조하기 때문에,

한쪽에 한쪽에 대한 접근이 다른 한쪽에도 영향을 미친다


이에 반해 깊은 복사

객체를 복사할 때 해당 객체와 인스턴스 변수까지 복사하여 새 주소에 담는다

 

이를 위해 보통 clone() 메소드를 이용한다 (Object 클래스)

이는 Cloneable 인터페이스추상메소드이다

(protected Object 메소드이므로 바로 사용할 수 없고, 메소드를 오버라이딩 하여 사용해야 한다)

 

오버라이딩 하는 코드는 다음과 같다

 

class Arr implements Cloneable {
    String name;
    Arr(String name) {
        this.name = name;
    }
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
// 후에 clone() 메소드 사용 시 CloneNotSupportedException 에러 try-catch

 


 

객체(Object)끼리의 비교 - Objects Class

 

Objects.equals(Object a, Object b)

: 두 객체의 동등을 비교한다

두 객체가 null이 아닌 경우에, a.equals(b) 의 결과를 리턴한다

 

Objects.deepEquals(Object a, Object b)

: 위의 메소드와 같이 두 객체의 동등을 비교한다

여기서 a와 b가 서로 다른 배열일 경우에,

배열의 항목 값이 모두 같을 때 true를 리턴한다 (이는 Arrays.deepEquals(Object[] a, Object[] b)와 같다)

 


 

배열(Array) 항목 비교 - Arrays Class

 

arr1.equals(arr2)

: 배열의 번지 비교

 

Arrays.equals(arr1, arr2)

: 배열의 1차 항목값만 비교

 

Arrays.deepEquals(arr1, arr2)

: 중첩 배열의 모든 항목값 비교

 

예시로, 다음은 이것이 자바다 배열 비교 코드이다

 

public static void main(String[] args) {
    int[][] arr1 = { {1,2}, {3,4} };
    
    // 얕은 복사
    int[][] arr2 = Arrays.copyOf(arr1, arr1.length);
    // arr1.equals(arr2) -> false
    // Arrays.equals(arr1, arr2) -> true
    // Arrays.deepEquals(arr1, arr2) -> true
    
    // 깊은 복사
    int[][] arr3 = Arrays.copyOf(arr1, arr1.length);
    arr3[0] = Arrays.copyOf(arr1[0], arr1[0].length);
    arr3[1] = Arrays.copyOf(arr1[1], arr1[1].length);
    // arr1.equals(arr3) -> false
    // Arrays.equals(arr1, arr3) -> false
    // Arrays.deepEquals(arr1, arr3) -> true

 

copyOf() 메소드는 전달받은 배열의 특정 길이만큼을 새로운 배열로 복사하여 반환한다

 

정리해보면, 아래 그림에서

arr1.equals(arr2) 는 파란색 상자 Object 끼리의 값과 주소 비교

Arrays.equals(arr1, arr2) 는 Object의 주소는 달라도 참조값은 같나 비교

Arrays.deepEquals(arr1, arr2) 는 Object와 참조값의 주소는 달라도 값은 같나 비교

를 의미한다

 

반응형