얕은 복사
- 복사 시 객체의 주소 값을 복사하여 동일한 주소 값을 가진다.
- 즉 원래 배열의 주솟값을 가져오는 것
- 같은 곳을 가리키기 때문에 한쪽에서 데이터를 변경하면 다른 한쪽도 변경된 데이터에 접근할 수 있다.
깊은 복사
- 복사 시 객체의 데이터 자체를 복사하여 다른 주솟값을 가진다.
- 즉 원래 배열을 그대로 가져오는 것
1차원 배열 복사
1. ' = ' 사용 [ 얕은 복사 ]
자바에서 객체를 ' = ' 을 통해 복사하게 되면 얕은 복사가 일어나 두 객체가 같은 곳을 바라보게 된다.
2. clone() 함수 사용 [ 깊은 복사 ]
만약 같은 공간을 가리키는 것이 아니라
배열의 값 자체를 복사하여 새로운 공간에 할당하고 주소를 받고 싶다면 배열의 clone() 함수를 사용하면 된다.
아래 코드를 돌려보면 arr1과 arr2는 같은 주소값을 가지지만
arr1과 arr3의 주소값은 다른 것을 확인할 수 있다.
public class Test{
public static void main(String[] args) throws Exception{
int[] arr1 = {1,2,3,4};
// 얕은 복사
int[] arr2 = arr1;
// 깊은 복사
int[] arr3 = arr1.clone();
arr1[3] = 5;
System.out.println("[arr1] : " + arr1 + " " + Arrays.toString(arr1));
System.out.println("[arr2] : " + arr2 + " " + Arrays.toString(arr2));
System.out.println("[arr3] : " + arr3 + " " + Arrays.toString(arr3));
}
}
2차원 배열 복사
1. ' = ' , arr2 = arr1.clone() [ 얕은 복사 ]
그렇다면 2차원 배열도 1차원 배열처럼 복사본을 넣을 배열 = 복사할 배열. clone()으로 복사가 가능할까?
그렇지 않다. 실제로 코드를 돌려보면 복사가 제대로 되지 않음을 알 수 있다.
public class Test{
public static void main(String[] args) throws Exception{
int[][] arr1 = {{1,2},{3,4},{5,6}};
// 얕은 복사
int[][] arr2 = arr1;
int[][] arr3 = arr1.clone();
arr1[2][0] = 10;
for(int i = 0; i < arr1.length; i++) {
System.out.print(Arrays.toString(arr1[i]) + " ");
}
System.out.println();
for(int i = 0; i < arr2.length; i++) {
System.out.print(Arrays.toString(arr2[i]) + " ");
}
System.out.println();
for(int i = 0; i < arr3.length; i++) {
System.out.print(Arrays.toString(arr3[i]) + " ");
}
}
}
그 이유는 객체를 복사한 것이 아닌 객체들을 담고 있는 주소의 주솟값 데이터들을 복사하였기 때문이다.
즉 1,2,4,7,8과 같은 데이터를 복사한 것이 아닌 이 데이터를 담고 있는 주소의 값을 가지고 있는 것이다.
2. 2중 for문 or 1중포문+[ clone() or System.arraycopy() ] [ 깊은 복사 ]
따라서 깊은 복사를 하기 위해서는 반복문을 사용해 객체를 각각 복사해야 한다.
2-1) 2중 for문
// 깊은 복사 (for문 + clone 사용)
for(int i = 0; i < arr1.length; i++) {
arr2[i] = arr1[i].clone();
}
2-2) 1중 for문 + clone()
// 깊은 복사 (2중 for문 사용)
for(int i = 0; i < arr1.length; i++) {
for(int j = 0; j < 2; j++) {
arr3[i][j] = arr1[i][j];
}
}
2-3) 1중 for문 + System.arraycopy(원래배열, 복사 시작 index, 새로운배열, 시작 index, 복사할 길이)
int[][] arr2 = new int[arr1.length][arr1[0].length];
for(int i = 0; i < arr1.length; i++){
System.arraycopy(arr1[i], 0, arr2[i], 0, arr1[i].length);
}
참고문헌
https://hanyeop.tistory.com/366
https://dev-note-97.tistory.com/36
'Java' 카테고리의 다른 글
[ Java ] int을 String으로, String을 int로 바꾸기 (0) | 2024.01.30 |
---|---|
[ JAVA ] Queue 클래스 (0) | 2023.11.06 |
[JAVA] ArrayList와 ArrayList 배열 (비정형 배열) (0) | 2023.11.04 |
Java - 오버라이딩(Overriding)과 오버로딩(Overloading) (0) | 2022.09.06 |
Java - 입력에서 문자(char) 하나 받아오기 (0) | 2022.09.05 |