고래씌
[JAVA] 5-2. 배열 복사(얕은 복사, 깊은 복사 본문
1. 배열 복사
1) 얕은 복사 : 배열의 주소값만 복사(원본 배열에 영향을 끼침)
// 배열 복사(얕은복사)
public void method1() {
// 원본 배열 셋팅
int[] origin = {1, 2, 3, 4, 5};
System.out.println("== 원본 배열 출력 ==");
for(int i=0; i<origin.length; i++) {
System.out.print(origin[i] + " ");
}
// 얕은복사
int [] copy = origin; // origin 배열에 저장된 주소값을 copy에 대입
// copy 주소값도 origin 주소값을 같이 공유해서 사용하고 있는 것!
System.out.println("\n== 카피 배열 출력 ==");
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i] + " ");
}
copy[0] = 99;
System.out.println("\n복사본 배열 변경후...");
System.out.println("== 원본 배열 출력 ==");
for(int i=0; i<origin.length; i++) {
System.out.print(origin[i] + " ");
}
System.out.println("\n== 카피 배열 출력 ==");
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i] + " ");
}
System.out.println();
System.out.println(origin.hashCode() == copy.hashCode());
}
☞ 복사본 배열만 가지고 수정을 했는데도 원본배열도 함께 수정이 된다. 이유는 얕은 복사가 이루어졌기 때문.
=> 배열의 주소값이 복사되어 원본과 복사본은 사실상 동일한 데이터를 공유하고 있다
2) 깊은 복사 : 동일한 새로운 배열을 하나더 만들어서 실제 내부값들을 복사(원본배열에 영향을 끼치지 않음)
(1) for문을 사용한 깊은 복사
public void method2() {
// 1. for문을 사용한 깊은 복사
// 값을 복사하기 위한 새로운 배열을 선언 및 할당하고,
// 각 인덱스별로 내부값을 일일이 대입하는 방법
int[] origin = {1, 2, 3, 4, 5};
int[] copy = new int[origin.length];
for(int i=0; i<copy.length; i++) {
copy[i] = origin[i];
}
// 복사가 잘 이루어졌는지 출력
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i] + " ");
}
copy[0] = 99;
System.out.println("\n복사본 배열 변경후...");
System.out.println("== 원본 배열 출력 ==");
for(int i=0; i<origin.length; i++) {
System.out.print(origin[i] + " "); // 1 2 3 4 5
}
System.out.println("\n== 카피 배열 출력 ==");
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i] + " "); // 99 2 3 4 5
}
System.out.println();
System.out.println(origin.hashCode() == copy.hashCode()); // 서로 다른 주소값을 바라보고 있다
}
☞ 서로 다른 주소값을 바라보고 있다!
(2) 새로운 배열을 생성한 후 System클래스 내부의 arraycopy메소드 사용
▶ System.arraycopy(원본 배열, 원본배열의 복사를 시작할 인덱스, 복사할 배열, 복사본 배열의 시작인덱스, 복사할 개수);
// 자바에서 제공하는 다양한 메소드를 사용
public void method3() {
// 2. 새로운 배열을 생성한 후 System클래스 내부의 arraycopy메소드 사용
int[] origin = {1, 2, 3, 4, 5};
int[] copy = new int[10];
// System.arraycopy(원본 배열, 원본배열의 복사를 시작할 인덱스, 복사할 배열, 복사본 배열의 시작인덱스, 복사할 개수);
System.arraycopy(origin, 0, copy, 3, 5);
int originIndex = 0;
for(int i=3; i<8; i++) {
copy[i] = origin[originIndex++];
System.out.print(copy[i]+ " ");
}
}
public void method3() {
// 2. 새로운 배열을 생성한 후 System클래스 내부의 arraycopy메소드 사용
int[] origin = {1, 2, 3, 4, 5};
int[] copy = new int[10];
// System.arraycopy(원본 배열, 원본배열의 복사를 시작할 인덱스, 복사할 배열, 복사본 배열의 시작인덱스, 복사할 개수);
System.arraycopy(origin, 0, copy, 0, 5); // 1 2 3 4 5 0 0 0 0 0
System.arraycopy(origin, 0, copy, 2, 5); // 0 0 1 2 3 4 5 0 0 0
System.arraycopy(origin, 2, copy, 1, 5); // 0 3 4 5 0 0 0 0 0 0 // 이렇게 하면 오류남
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i]+ " ");
}
}
☞ System.arraycopy() : 몇번 인덱스부터 몇개를 복사본 배열의 어느 위치에 복사할건지 세밀하게 설정 가능함
(3) Arrays 클래스에서 제공하는 copyOf 메소드 사용
public void method4() {
// 3. Arrays 클래스에서 제공하는 copyOf메소드 사용
int[] origin = {1, 2, 3, 4, 5};
// 복사본 배열 = Arrays.copyOf(원본배열명, 복사할 갯수)
int[] copy = Arrays.copyOf(origin, 8);
int[] copy2 = new int[3];
for(int i=0; i<3; i++) {
copy2[i] = origin[i];
}
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i] + " ");
}
☞ Arrays.copyOf() : 무조건 원본배열의 0번 인덱스부터 내가 제시한 개수만큼 복사가 진행됨.
내가 제시한 길이가 원본배열보다 크다면? 그외의 값들은 0으로 채워서 복사해줌
(4) clone 메소드 사용
int [] origin = {1,2,3,4,5};
int [] copy = origin.clone();
Arrays.toString(배열) -> 출멱문 앞과 뒤에 [] 붙이고 각 값마다 , 를 넣어서 하나의 "문자열"로 연이어서 출력해주는 메소드
public void method5() {
// 4. clone 메소드를 사용
int [] origin = {1, 2, 3, 4, 5};
int [] copy = origin.clone();
// 무조건 원본 배열과 동일한 값을 가진 복사본 배열이 반환
for(int i=0; i<copy.length; i++) {
System.out.print(copy[i] + " ");
}
/*
* Arrays.toString(배열)
* -> 출력문 앞과 뒤에 [] 붙이고, 각 값마다 , 를 넣어서 하나의 "문자열"로 연이어서 출력해주는 메소드
*/
System.out.println();
System.out.println(Arrays.toString(copy));
System.out.println(origin == copy);
}
'JAVA > JAVA 기초' 카테고리의 다른 글
[JAVA] 7. 객체(추상화, 캡슐화) (0) | 2023.10.11 |
---|---|
[JAVA] 6. 2차원 배열 (0) | 2023.10.11 |
[JAVA] 5-1. 배열 실습문제 (0) | 2023.10.11 |
[JAVA] 5. 배열 (0) | 2023.10.10 |
[JAVA] 4-4. 제어문(while문), break, continue (0) | 2023.10.06 |