💁♀️ 배열의 복사 (Array Copy)란,
객체를 복사하는 유형으로 깊은 복사와 얕은 복사가 있는데, 깊은 복사의 경우 객체의 실제값을 새로운 객체로 복사하는 것이고 얕은 복사는 단순히 객체의 주소 값만을 복사하는 것
💁♀️ stack의 주소값만 복사
// 원본 배열 생성
int[] originArr = {1, 2, 3, 4, 5};
// 원본 배열을 복사 배열에 복사
int[] copyArr = originArr;
// hashcode 출력해서 확인
System.out.println(originArr.hashCode());
System.out.println(copyArr.hashCode());
>>> 서로 동일한 주소값을 확인 할 수 있음 (얕은 복사 완료)
// 복사본 배열을 통해 값 변경 후 출력
>>> 복사본 배열만 변경하더라도 원본 배열에 영향을 미침을 알 수 있음
>>> 서로 '같은 배열을 참조'하고 있기 때문
copyArr[0] = 99;
>>> copyArr의 인덱스 0번 자리의 값이 1대신 99로 변경됨
for(int i = 0; i < originArr.length; i++) {
System.out.print(originArr[i] + " ");
}
System.out.println();
for(int i = 0; i < copyArr.length; i++) {
System.out.print(copyArr[i] + " ");
}
System.out.println();
>>> 두 배열 모두 인덱스 0번 자리의 값이 99로 변경 된 것을 확인 할 수 있음
주로 메소드 호출 시 인자로 사용하는 경우와 리턴 값으로 동일한 배열을 리턴해주고 싶은 경우 사용
public static void main(String[] args) {
String[] names = {"유관순", "홍길동", "신사임당"};
System.out.println("name의 hashcode : " + names.hashCode());
>>> print 메소드에 names 배열을 인자로 전달
>>> print(names); : names 배열의 주소값을 sarr로 보내는 역할
>>> 메소드명(보낼배열의이름)
}
public static void print(String[] sarr) {
>>> print(String sarr 배열)메소드로 names 배열이 도착
System.out.println("sarr의 hashcode : " + sarr.hashCode());
>>> 같은 주소값 출력 -> 같은 배열을 참조하고있음(얕은 복사)
for(int i = 0; i < sarr.length; i++) {
System.out.println(sarr[i] + " ");
}
System.out.println();
}
💻 Mini Console
name의 hashcode : 1956710488
sarr의 hashcode : 1956710488
유관순
홍길동
신사임당
public static void main(String[] args) {
String[] animals = getAnimals();
>>> 메소드 호출하면 getAnimals 메소드의 리턴값이 animals 변수에 저장됨
System.out.println("리턴 받은 animals의 hashcode : " + animals.hashCode());
}
public static String[] getAnimals() {
String[] bigAnimals = {"낙타", "호랑이", "나무늘보"};
System.out.println("새로 만든 animals의 hashcode : " + bigAnimals.hashCode());
return bigAnimals;
>>> 리턴값은 문자열, 배열의 주소값이 리턴됨 (배열의 값들을 넘기는 것이 아님)
}
💻 Mini Console
새로 만든 animals의 hashcode : 603856241
리턴 받은 animals의 hashcode : 603856241
💁♀️ heap의 배열에 저장된 값을 복사
📍 깊은 복사를 하는 방법
1) for문을 이용한 동일한 인덱스 값 복사
2) Object의 clone()을 이용한 복사
3) System의 arraycopy()를 이용한 복사
4) Arrays의 copyOf()를 이용한 복사
// 원본 배열
int[] originArr = {1, 2, 3, 4, 5};
int[] copyArr1 = new int[10];
for(int i = 0; i < originArr.length; i++) {
copyArr1[i] = originArr[i];
}
print(originArr);
print(copyArr1);
>>> 아래에 있는 프린트용 print 메소드를 이용함
💻 Mini Console
iarr의 hashcode : 1956710488
1 2 3 4 5
iarr의 hashcode : 603856241
1 2 3 4 5 0 0 0 0 0
// 원본 배열
int[] originArr = {1, 2, 3, 4, 5};
int[] copyArr2 = originArr.clone();
print(copyArr2);
>>> 아래에 있는 프린트용 print 메소드를 이용함
💻 Mini Console
iarr의 hashcode : 682376643
1 2 3 4 5
// 원본 배열
int[] originArr = {1, 2, 3, 4, 5};
int[] copyArr3 = new int[10];
>>> (원본 배열, 복사를 시작할 인덱스, 복사본 배열, 복사를 시작할 인덱스, 복사할 길이)의 의미
System.arraycopy(originArr, 0, copyArr3, 3, originArr.length);
print(copyArr3);
>>> 아래에 있는 프린트용 print 메소드를 이용함
💻 Mini Console
iarr의 hashcode : 854507466
0 0 0 1 2 3 4 5 0 0
// 원본 배열
int[] originArr = {1, 2, 3, 4, 5};
>>> 시작 인덱스부터 원하는 길이만큼만 복사해서 사용 가능
int[] copyArr4 = Arrays.copyOf(originArr, 7);
>>> 7이 원하는 길이고, 늘릴수록 0이 더 생성됨
print(copyArr4);
>>> 아래에 있는 프린트용 print 메소드를 이용함
💻 Mini Console
iarr의 hashcode : 1316061703
1 2 3 4 5 0 0
public static void print(int[] iarr) {
System.out.print("iarr의 hashcode : " + iarr.hashCode());
>>> 하나의 배열을 참조 (얕은 복사됨)
System.out.println();
for(int i = 0; i < iarr.length; i++) {
System.out.print(iarr[i] + " ");
}
System.out.println();
}
📌 Ref.
* 깊은 복사는 heap에 생성된 배열이 가지고 있는 값을 또 다른 배열에 복사하는 것
* 서로 같은 값을 가지고 있지만, 두 배열은 서로 다른 배열이기에 하나의 배열을 변경해도 다른 배열에 영향을 주지 않음
💁 배열 인덱스에 하나씩 차례로 접근해서 담긴 값을 임시로 사용할 변수에 담고 반복문을 실행
for (해당자료형 변수명 : 배열명)
ex) for( int i : arr2 )
>>> 두 개의 같은 값을 가지는 배열 생성
int[] arr1 = {1, 2, 3, 4, 5}; >>> 일반 for문에 사용
int[] arr2 = arr1.clone(); >>> 향상된 for문에 사용
for(int i = 0; i < arr1.length; i++) {
arr1[i] += 10;
}
for(int i = 0; i < arr1.length; i++) {
System.out.println(arr1[i]);
}
💻 Mini Console
11
12
13
14
15
for(int i : arr2) { >>> 변수 i에 0부터 계속 차곡차곡 담김
System.out.print(i + " ");
}
💻 Mini Console
1 2 3 4 5
for(int i : arr2) {
i += 10;
}
>>> 임시변수 i를 이용하여 값을 출력 및 연산(사용)할 때는 편리하지만
>>> 인덱스의 값을 바꿀 수도 없고 건드릴 수도 없음
for(int i : arr2) {
System.out.print(i + " ");
}
💻 Mini Console
1 2 3 4 5
>>> 증가되지않고 그대로 출력됨
향상된 for문은 배열 인덱스에 차례로 접근할 때는 편하게 사용할 수 있지만 '값을 변경할 수는 없음'
대신 변경이 아니라 '사용'이 목적인 경우 사용하기에는 편리
double[] darr = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6};
for(double d : darr) {
System.out.print(d + " ");
}