선요약
얕은 복사: 복사한 배열이 원래 배열의 주솟값을 가져옴
깊은 복사: 복사한 배열이 원래 배열을 그대로 가져옴
public class ArrCopy {
public static void main(String[] args) {
int[] a = new int[3];
a[0] = 2;
a[1] = 4;
a[2] = 6;
int[] b = a;
for(int i = 0; i<a.length; i++) {
System.out.printf("%d ", a[i]); //2 4 6
}
System.out.println();
for(int i = 0; i<a.length; i++) {
System.out.printf("%d ", b[i]);//2 4 6
}
}
}
이 코드에서 얕은 복사를 하면 어떻게 될까?
public class ArrCopy {
public static void main(String[] args) {
int[] a = new int[3];
a[0] = 2;
a[1] = 4;
a[2] = 6;
int[] b = a;
b[0] = 3;
b[1] = 6;
for(int i = 0; i<a.length; i++) {
System.out.printf("%d ", a[i]); //3 6 6
}
System.out.println();
for(int i = 0; i<a.length; i++) {
System.out.printf("%d ", b[i]); //3 6 6
}
}
}
복사한 배열을 수정하니 이전 원본 배열도 함께 수정되었다.
import java.util.Arrays;
public class ArrCopy {
public static void main(String[] args) {
int[][] a = {{2, 4, 6},
{3, 6, 9},
{4, 8, 12}};
int[][] b = a;
b[2][2] = 4;
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(a[i]) + "");
}
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(b[i]) + "");
}
}
}
output
[2, 4, 6]
[3, 6, 9]
[4, 8, 4]
[2, 4, 6]
[3, 6, 9]
[4, 8, 4]
public class ArrCopy {
public static void main(String[] args) {
int[] math = {1, 2, 3, 4, 5};
int[] newMath = new int[5];
newMath = math;
System.out.println("얕은 복사 결과");
for (int i = 0; i < math.length; i++) {
if (i == 0)
System.out.printf("math데이터: ");
System.out.printf("%d ", math[i]);
}
System.out.println("math의 주소: " + math);
for(int i = 0; i<math.length; i++){
if (i == 0)
System.out.printf("newMath데이터: " );
System.out.printf("%d " , newMath[i]);
}
System.out.println("newMath의 주소: " + newMath);
}
}
얕은 복사 결과
math데이터: 1 2 3 4 5 math의 주소: [I@6d8a00e3
newMath데이터: 1 2 3 4 5 newMath의 주소: [I@6d8a00e3
import java.util.Arrays;
public class ArrCopy {
public static void main(String[] args) {
int[] a = {2, 4, 6};
int[] b = a.clone();
a[2] = 5;
System.out.println("a 주소: " + a + " " + Arrays.toString(a));
System.out.println("b 주소: " + b + " " + Arrays.toString(b));
}
}
output
a 주소: [I@22f71333 [2, 4, 5]
b 주소: [I@13969fbe [2, 4, 6]
import java.util.Arrays;
public class ArrCopy {
public static void main(String[] args) {
int[] a = {2, 4, 6};
int[] b = a.clone();
b[0] = 100;
System.out.println("a: " + Arrays.toString(a)); //a: [2, 4, 6]
System.out.println("b: " + Arrays.toString(b)); //b: [100, 4, 6]
}
}
그런데..
public class ArrCopy {
public static void main(String[] args) {
int[][] a = {{2, 4, 6},
{3, 6, 9},
{4, 8, 12}};
int[][] b = a.clone(); //깊은 복사
b[1][2] = 11;
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(a[i]) + "");
}
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(b[i]) + "");
}
}
}
이와 같은 2차원 배열은 깊은 복사를 했는데 얕은 복사가 되어버렸다.
[2, 4, 6]
[3, 6, 11]
[4, 8, 12]
[2, 4, 6]
[3, 6, 11]
[4, 8, 12]
해결방법 1: for문 + clone
import java.util.Arrays;
public class ArrCopy {
public static void main(String[] args) {
int[][] a = {{2, 4, 6},
{3, 6, 9},
{4, 8, 12}};
int[][] b = new int[3][3];
for(int i = 0; i<a.length; i++) {
b[i] = a[i].clone();
}
b[2][2] = 4;
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(a[i]) + "");
}
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(b[i]) + "");
}
}
}
해결방법 2: 2중 for문
import java.util.Arrays;
public class ArrCopy {
public static void main(String[] args) {
int[][] a = {{2, 4, 6},
{3, 6, 9},
{4, 8, 12}};
int[][] b = new int[3][3];
for(int i = 0; i<a.length; i++) {
for(int j = 0; j<a[i].length; j++){
b[i][j] = a[i][j];
}
}
b[2][2] = 4;
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(a[i]) + "");
}
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(b[i]) + "");
}
}
}
해결방법 3. System.arraycopy()
import java.util.Arrays;
public class ArrCopy {
public static void main(String[] args) {
int[][] a = {{2, 4, 6},
{3, 6, 9},
{4, 8, 12}};
int[][] b = new int[a.length][a[0].length]; //a와 같은 사이즈로 선언 후
for(int i = 0; i<a.length; i++){
System.arraycopy(a[i],0,b[i],0,b[i].length); //복사
}
b[2][2] = 4;
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(a[i]) + "");
}
for (int i = 0; i < a.length; i++) {
System.out.println(Arrays.toString(b[i]) + "");
}
}
}
이 3가지 경우 모두
output
[2, 4, 6]
[3, 6, 9]
[4, 8, 12]
[2, 4, 6]
[3, 6, 9]
[4, 8, 4]
public class ArrCopy {
public static void main(String[] args) {
int[] math = {1, 2, 3, 4, 5};
int[] newMath = new int[5];
System.out.println("math의 주소: " + math);
System.out.println("newMath의 주소: " + newMath);
for(int i = 0; i<math.length; i++)
newMath[i] = math[i];
for(int i = 0; i<newMath.length; i++){
if(i == 0)
System.out.printf("newMath 데이터: " );
System.out.printf("%d ", newMath[i]);
}
System.out.println();
int[] mathClone = math.clone();
System.out.println("mathClone의 주소: " + mathClone);
for(int i = 0; i<mathClone.length; i++){
if(i ==0)
System.out.printf("mathClone 데이터: ");
System.out.printf("%d ", mathClone[i]);
}
System.out.println();
for(int i = 0; i<newMath.length; i++)
newMath[i] = 0;
System.arraycopy(math,2,newMath,0,2);
for(int i = 0; i<newMath.length; i++){
if(i == 0)
System.out.printf("newMath 데이터: " );
System.out.printf("%d ", newMath[i]);
}
System.out.println();
}
}
math의 주소: [I@b684286
newMath의 주소: [I@880ec60
newMath 데이터: 1 2 3 4 5
mathClone의 주소: [I@7ac7a4e4
mathClone 데이터: 1 2 3 4 5
newMath 데이터: 3 4 0 0 0