깊은 복사 얕은 복사

김재익·2023년 6월 13일
0

JAVA

목록 보기
3/18
post-thumbnail

얕은 복사

배열, 컬렉션, 객체 등 참조 타입의 값은 생성시 주소가 생기고 대입으로 복사 했을 때 주소가 저장된다.

두 변수 모두 같은 값을 가지고 있지만 같은 주소를 가지고 있기 때문에 둘 중 하나를 수정하면 다른 하나도 같이 수정된다.
ex)

// 얕은 복사

int[] a = { 1, 2, 3, 4 };
int[] b = a; // 얕은 복사

b[0] = 3; // b 배열의 0번째 순번값을 3으로 수정했습니다. (1 -> 3)

System.out.println(a[0]); // 출력 3  <- a 배열의 0번째 순번값도 3으로 조회됩니다. 

깊은 복사

얕은 복사의 경우 값을 조회하는 경우에 사용되는 것은 문제가 안되나 값의 수정이 필요한 경우 즉, 독립된 두 변수가 값은 동일한 것을 원할 경우 문제가 된다.

그래서 변수가 내포하고있는 값을 직접 복사해줘야 한다.

ex)

// 깊은 복사

int[] a = { 1, 2, 3, 4 };
int[] b = new int[a.length]; 

for (int i = 0; i < a.length; i++) {
    b[i] = a[i]; // 깊은 복사
}

b[0] = 3; // b 배열의 0번째 순번값을 3으로 수정했습니다. (1 -> 3)

System.out.println(a[0]); // 출력 1 <- 깊은 복사를 했기때문에 a 배열은 그대로 입니다.

자바의 경우 .clone() 이라는 메서드로 깊은 복사를 지원한다.

// 깊은 복사 메서드

// 1. clone() 메서드
int[] a = { 1, 2, 3, 4 };
int[] b = a.clone(); // 가장 간단한 방법입니다. 
// 하지만, clone() 메서드는 2차원이상 배열에서는 얕은 복사로 동작합니다!!

자바의 배열은 .copyOf()라는 깊은 복사 함수를 지원한다.

// 깊은 복사 메서드

import java.util.Arrays;

public class Main {
	public static void main(String[] args) {
		// 2. Arrays.copyOf() 메서드
		int[] a = { 1, 2, 3, 4 };
		int[] b = Arrays.copyOf(a, a.length); // 배열과 함께 length값도 같이 넣어줍니다.
	}
}

2차원 이상의 배열(or 객체배열, collection)

위에 적힌 대로 2차원 배열 혹은 객체의 배열 같은 경우 clone으로 복사 하여도 얕은 복사로 시행된다 왜냐하면 clone의 경우 a의 내부 값만 복사하는 것이기 때문이다.

a가 주소를 값으로 가진 경우엔 clone으로 그 형태만 복사해온다.

ex) 객체 리스트

//Student라는 클래스가 있습니다.
List<Student> arr1 = new ArrayList<>();
for (int i = 0; i < 5 ; i++) {
	arr1.add(new Student("jack", "1234"));
}
ArrayList<Student> arr2 = (ArrayList<Student>) arr1.clone();

System.out.println("arr1 = " + arr1);
System.out.println("arr2 = " + arr2);

arr2.get(1).setName("tom");

System.out.println("arr1 = " + arr1);
System.out.println("arr2 = " + arr2);

result)

.clone() 외에도 List.addAll() Collections.copy() 등등 다양한 복사 메서드가 있다.

다양한 복사 메서드가 있지만 2차원 배열의 깊은 복사를 하기 위해선 개발자가 직접 복사하는 수 밖에 없다.

ex) 객체 리스트

List<Student> arr1 = new ArrayList<>();
for (int i = 0; i < 5 ; i++) {
    arr1.add(new Student("jack", "1234"));
}
// ArrayList<Student> arr2 = (ArrayList<Student>) arr1.clone();
List<Student> arr2 = new ArrayList<>();
for(Student s : arr1){
    arr2.add(new Student(s.getName(),s.getStudentNumber()));
}
System.out.println("arr1 = " + arr1);
System.out.println("arr2 = " + arr2);

arr2.get(1).setName("tom");

System.out.println("arr1 = " + arr1);
System.out.println("arr2 = " + arr2);

profile
개발자호소인

0개의 댓글