배열의 복사 (Array Copy)

Joy🌱·2022년 12월 29일
0

☕ Java

목록 보기
13/40
post-thumbnail

💁‍♀️ 배열의 복사 (Array Copy)란,
객체를 복사하는 유형으로 깊은 복사와 얕은 복사가 있는데, 깊은 복사의 경우 객체의 실제값을 새로운 객체로 복사하는 것이고 얕은 복사는 단순히 객체의 주소 값만을 복사하는 것


👀 얕은 복사(shallow copy)

💁‍♀️ stack의 주소값만 복사

1) 얕은 복사

// 원본 배열 생성
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로 변경 된 것을 확인 할 수 있음

2) 얕은 복사의 활용

주로 메소드 호출 시 인자로 사용하는 경우리턴 값으로 동일한 배열을 리턴해주고 싶은 경우 사용

[1] 인자로 사용하는 경우

◼ main method

public static void main(String[] args) {
	String[] names = {"유관순", "홍길동", "신사임당"};
	System.out.println("name의 hashcode : " + names.hashCode());
    
>>> print 메소드에 names 배열을 인자로 전달
>>> print(names); : names 배열의 주소값을 sarr로 보내는 역할
>>> 메소드명(보낼배열의이름)
}

◼ print(String[] sarr) method

배열을 매개변수로 받아 모든 인덱스에 저장되어있는 값을 출력하는 기능을 제공하는 메소드
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
유관순 
홍길동 
신사임당

[2] 리턴 값으로 동일한 배열을 리턴해주고 싶은 경우

◼ main method

public static void main(String[] args) {

	String[] animals = getAnimals();
    >>> 메소드 호출하면 getAnimals 메소드의 리턴값이 animals 변수에 저장됨
	System.out.println("리턴 받은 animals의 hashcode : " + animals.hashCode());
}

◼ String[] getAnimals() method

동물 종류로 생성된 문자열 배열을 반환하는 메소드
public static String[] getAnimals() {
		
	String[] bigAnimals = {"낙타", "호랑이", "나무늘보"};
		
	System.out.println("새로 만든 animals의 hashcode : " + bigAnimals.hashCode());
		
	return bigAnimals;
    >>> 리턴값은 문자열, 배열의 주소값이 리턴됨 (배열의 값들을 넘기는 것이 아님)
}

💻 Mini Console

새로 만든 animals의 hashcode : 603856241
리턴 받은 animals의 hashcode : 603856241

👀 깊은 복사(deep copy)

💁‍♀️ heap의 배열에 저장된 값을 복사

1) 깊은 복사

📍 깊은 복사를 하는 방법

1) for문을 이용한 동일한 인덱스 값 복사 
2) Object의 clone()을 이용한 복사
3) System의 arraycopy()를 이용한 복사 
4) Arrays의 copyOf()를 이용한 복사 

[1] for문을 이용한 동일한 인덱스 값 복사

// 원본 배열
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 

[2] Object의 clone()을 이용한 복사

// 원본 배열
int[] originArr = {1, 2, 3, 4, 5};

int[] copyArr2 = originArr.clone();

print(copyArr2);
>>> 아래에 있는 프린트용 print 메소드를 이용함

💻 Mini Console

iarr의 hashcode : 682376643
1 2 3 4 5 

[3] System의 arraycopy()를 이용한 복사

// 원본 배열
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 

[4] Arrays의 copyOf()를 이용한 복사

// 원본 배열
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문 (for-each문)

💁‍ 배열 인덱스에 하나씩 차례로 접근해서 담긴 값을 임시로 사용할 변수에 담고 반복문을 실행
for (해당자료형 변수명 : 배열명)
ex) for( int i : arr2 )

>>> 두 개의 같은 값을 가지는 배열 생성
int[] arr1 = {1, 2, 3, 4, 5}; >>> 일반 for문에 사용
int[] arr2 = arr1.clone(); >>> 향상된 for문에 사용

1) 일반 for문 이용

[1] 일반 for문을 이용해 인덱스에 10씩 누적 증가

for(int i = 0; i < arr1.length; i++) {
	arr1[i] += 10;
}

[2] 일반 for문을 이용해 값 출력

for(int i = 0; i < arr1.length; i++) {
	System.out.println(arr1[i]);
}

💻 Mini Console

11
12
13
14
15

2) 향상된 for문 이용

[1] 향상된 for문으로 배열의 값 출력

for(int i : arr2) { >>> 변수 i에 0부터 계속 차곡차곡 담김 
	System.out.print(i + " ");
}

💻 Mini Console

1 2 3 4 5 

[2] 향상된 for문을 이용해서 값 증가 시키기

for(int i : arr2) { 
	i += 10;
} 
>>> 임시변수 i를 이용하여 값을 출력 및 연산(사용)할 때는 편리하지만 
>>> 인덱스의 값을 바꿀 수도 없고 건드릴 수도 없음

[3] 증가되었는지 출력 확인

for(int i : arr2) { 
	System.out.print(i + " ");
}

💻 Mini Console

1 2 3 4 5 
>>> 증가되지않고 그대로 출력됨

😈 Warning

향상된 for문은 배열 인덱스에 차례로 접근할 때는 편하게 사용할 수 있지만 '값을 변경할 수는 없음'
대신 변경이 아니라 '사용'이 목적인 경우 사용하기에는 편리

🔥중요🔥 향상된 for문으로 출력하기

double[] darr = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6};
		
for(double d : darr) { 
	System.out.print(d + " ");
}

profile
Tiny little habits make me

0개의 댓글

관련 채용 정보