[Java] copy(배열의 복사)
카테고리: Java
태그: coding Programming Java
배열의 복사
- 배열의 복사에는 두 종류가 있다
- 얕은 복사 : stack 의 주소값만 복사
- 깊은 복사 : heap 의 배열에 저장한 값을 복사
- 얕은 복사는 stack 에 저장되어 있는 배열의 주소값만 복사한다는 것이다
- 따라서 두 개의 래퍼런스 변수는 동일한 배열의 주소값을 가지고 있다
- 하나의 래퍼런스 변수에 저장된 주소값을 가지고 배열의 내용을 수정(값 변경)을 하게되면
- 다른 래퍼런스 변수로 배열에 접근했을 때도 동일한 배열을 가르키고 있기 때문에 변경된 값이 반영되었다
package section03.copy;
public class Application1 {
public static void main(String[] args) {
int[] originArr = {1, 2, 3, 4, 5};
int[] copy = originArr; // 얕은 복사
System.out.println("originArr = " + originArr.hashCode());
System.out.println("copy = " + copy.hashCode());
for (int i = 0; i < originArr.length; i++) {
System.out.print(originArr[i] + " ");
}
System.out.println();
for (int i = 0; i < originArr.length; i++) {
System.out.print(copy[i] + " ");
}
System.out.println();
}
}
- 출력값
originArr = 1283928880
copy = 1283928880
1 2 3 4 5
1 2 3 4 5
얕은 복사를 활용하여 매개변수와 리턴값으로 활용할 수 있다
얕은 복사의 활용
- 얕은 복사를 활용하는 것은 주로 메소드 호출시 인자로 사용하는 경우와
- 리턴값으로 동일한 배열을 리턴해주고 싶은 경우 사용한다
package section03.copy;
public class Application2 {
public static void main(String[] args) {
String[] name = {"홍길동", "유관순", "이순신"};
System.out.println("name.hashCode() = " + name.hashCode()); //1283928880
/* 1. 인자와 매개변수로 활용 */
print(name);
/* 2. 리턴값으로 활용 */
String[] animals = getAnimals();
System.out.println("리턴 받은 animals.hashcode() = " + animals.hashCode());
print(animals); // 1989780873
}
public static void print(String[] sarr) {
System.out.println("sarr.hashCode() = " + sarr.hashCode()); // 1283928880
for (int i = 0; i < sarr.length; i++) {
System.out.print(sarr[i] + " ");
}
System.out.println();
}
public static String[] getAnimals() {
String[] animals = new String[] {"뱀", "판다", "다람쥐"};
System.out.println("새로만든 animals의 hashcode = " + animals.hashCode());
return animals;
}
}
- 출력값
name.hashCode() = 1283928880
sarr.hashCode() = 1283928880
홍길동 유관순 이순신
새로만든 animals의 hashcode = 1989780873
리턴 받은 animals.hashcode() = 1989780873
sarr.hashCode() = 1989780873
뱀 판다 다람쥐
깊은 복사에 대해 이해할 수 있다
- 깊은 복사는 heap 에 생성된 배열이 가지고 있는 값을
- 또 다른 배열에 복사를 해놓은 것이다
- 서로 같은 값을 가지고 있지만, 두 배열은 서로 다른 배열이기 때문에
- 하나의 배열을 변경 하더라도 다른 배열에는 영향을 주지 않는다
깊은 복사를 하는 방법은 4가지가 있다
- for 문을 이용한 동일한 인덱스 값 복사
- Object 의 clone()을 이용한 복사
- System의 arraycopy()를 이용한 복사
- Array의 copyOf()를 이용한 복사
- 이중에서 가장 높은 성능을 보이는 것은 순수 배열의 복사를 위해 만들어진 arraycopy()메소드이며,
- 가장 많이 사용되는 방식은 좀 더 유연한 방식인 copyOf() 메소드이다
- clone()은 이전 배열과 같은 배열밖에 만들 수 없다는 특징을 가지고
- 그 외 3가지 방법은 복사하는 길이의 배열의 길이를 마음대로 조절할 수 있다는 특징을 가지고 있다
package section03.copy;
import java.util.Arrays;
public class Application3 {
public static void main(String[] args) {
int[] originArr = new int[]{1, 2, 3, 4, 5}; //1283928880
print(originArr);
/*1. for문을 통해서 동일한 인덱스 값 복사 */
int[] copyArr = new int[10];
for(int i = 0; i < originArr.length; i++){
copyArr[i] = originArr[i];
}
print(copyArr);
/* 2.Object의 clone()을 이용한 복사 */
int[] copyArr2 = originArr.clone();
print(copyArr2);
/* 3. System의 arraycopy()을 이용한 복사 */
int[] copyArr3 = new int[10]; //81628611
/* 원본배열. 복사를 시작할 인덱스, 복사할 배열, 복사를 시작할 인덱스, 복사할 길이릐 의미를 가진다. */
System.arraycopy(originArr,0,copyArr3,3,originArr.length);
print(copyArr3);
/* 4.Array의 copyOf()을 이용한 복사 */
int[] copyArr4 = Arrays.copyOf(originArr,7);
print(copyArr4);
}
public static void print(int[] iarr) {
System.out.println("iarr.hashCode() = " + iarr.hashCode()); // 1283928880
for (int i = 0; i < iarr.length; i++) {
System.out.print(iarr[i] + " ");
}
System.out.println();
}
}
- 출력값
iarr.hashCode() = 1283928880
1 2 3 4 5
iarr.hashCode() = 1989780873
1 2 3 4 5 0 0 0 0 0
iarr.hashCode() = 1480010240
1 2 3 4 5
iarr.hashCode() = 81628611
0 0 0 1 2 3 4 5 0 0
iarr.hashCode() = 1828972342
1 2 3 4 5 0 0
배열의 깊은 복사를 사용한 자바문법을 이해하고 활용할 수 있다
- 깊은 복사는 원본과 복사본 중 둘 중 한가지 값을 변경해도 다른 하나에 영향을 주지 않는다
- 값은 값을 가지고 있는 서로 다른 배열이기 때문이다
package section03.copy;
public class Application4 {
public static void main(String[] args) {
int[] arr1 = {1,2,3,4,5};
int[] arr2 = arr1.clone();
for(int i = 0; i<arr1.length; i++){
arr1[i] +=10;
}
for(int i = 0; i < arr1.length; i++){
System.out.print(arr1[i] + " ");
}
System.out.println();
/* 향상된 for문 : jdk 1.5버전부터 추가되었다 */
/*배열 인덱스에 하나씩 차례로 접근해서 담긴 값을 임시로 사용할 변수에 담고 반복문을 실행한다.
* */
for(int i : arr2){
i+=10;
}
for(int i = 0; i < arr2.length; i++){
System.out.print(arr2[i] + " ");
}
System.out.println();
}
}
- 출력값
11 12 13 14 15
1 2 3 4 5
요약. 1. 얕은 복사 : stack의 주소값만 복사 2. 깊은 복사 : heap의 배열에 저장한 값을 복사
조금더 부지런하게 움직이자!!
댓글 남기기