배열의 복사
배열의 복사에는 크게 두가지 종류가 있다.
1. 얕은 복사 (shallow copy) : 스택의 주소값만 복사
얕은 복사는 스택에 저장되어 있는 배열의 주소값만 복사한다는 것이다.
따라서 두개의 래퍼런스 변수는 동일한 배열의 주소값을 가지고 있다.
하나의 래퍼런스 변수에 저장된 주소값을 가지고 배열의 내용을 수정(값 변경)을 하게되면
다른 레퍼런스 변수로 배열을 접근했을 때도 동일한 배열을 가리키고 있기 때문에 변경된 값이 반영되어 있다.
/*얕은 복사를 확인할 원본 배열 생성*/
int[] originArr = {1,2,3,4,5};
/*카피할 배열*/
int[] copyArr = originArr;
/* hashcode를 출력해보면 두 개의 래퍼런스 변수는
동일한 주소를 가지고 있는 것을 볼수 있다.*/
System.out.println(originArr.hashCode());
System.out.println(copyArr.hashCode());
/*원본 배열과 복사본 배열의 값 출력*/
/*두 배열은 동일한 값을 가지고 있다.*/
/* 복사본 배열에 값을 변경한 뒤 다시 값을 확인해보면
* 복사본 배열만 변경했음에도 원본 배열에 영향을 미침을 알수 있다.
* 서로 같은 배열을 가리키고 있기 때문이다 (현재 존재하는 배열은 하나 뿐이다.)
* */
copyArr[0] = 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();
}
}
얕은 복사의 활용
얕은 복사를 활용하는 것은 주로 메소드 호출시 인자로 사용하는 경우와
리턴값으로 동일한 배열을 리턴해주고 싶은 경우 사용한다.
2. 깊은 복사 (deep copy) : 힙 배열에 저장된 값을 복사
깊은 복사는 heap에 생성된 배열이 가지고 있는 값을 또 다른 배열에 복사를 해놓은 것이다.
서로 같은 값을 가지고 있지만, 두 배열은 서로 다른 배열이기에
하나의 배열을 변경하더라도 다른 배열에는 영향을 주지 않는다
깊은 복사를 하는 방법은 4가지가 있다.
1. for문을 이용한 동일한 인덱스의 값 복사
원본 배열과 복사한 값은 같은 값을 가지고 나머지 인덱스는 다른 값, 다른 주소를 가지고 있다.
int[] copyArr1 = new int[10];
for (int i = 0; i < originArr.length; i++) {
copyArr1[i] = originArr[i];
}
2. Object의 clone()을 이용한 복사
동일한 길이, 동일한 값을 가지는 배열이 생성되어 복사 되며, 다른 주소를 가지고 있다.
int[] copyArr2 = originArr.clone();
3. System의 arrycopy()를 이용한 복사
원본배열, 복사를 시작할 인덱스, 복사본 배열, 복사를 시작할 인덱스, 복사할 길이의 의미를 가진다.
System.arraycopy(originArr, 0, copyArr3, 3, originArr.length);
복사한 만큼의 값은 같지만 길이도 다르고 주소도 다르다
4. Arrays의 copyOf()를 이용한 복사
시작 인덱스부터 원하는 길이만큼만 복사해서 사용 가능하다.
int[] copyArr4 = Arrays.copyOf(originArr, 7);
복사한 만큼의 값은 같지만 길이도 다르고 주소도 다르다
이중 가장 높은 성능을 보이는 것은 순수 배열의 복사를 위해 만들어진 arraycopy() 메소드이며
가장 많이 사용되는 방식은 좀 더 유연한 방식인 copyOf() 메소드이다.
clone()은 이전 배열과 같은 배열밖에 만들 수 없다는 특징을 가지고
그 외 3가지 방법은 복사하는 배열의 길이를 마음대로 조절할 수 있다는 특징을 가지고있다.
향상된 for문 : jdk 1.5 버전부터 추가
배열 인덱스에 하나씩 차례로 접근해서 담긴 값을 임시로 사용할 변수를 담고 반복문을 실행한다.
/*두 개의 같은 값을 가지는 배열을 만든다.*/
int[] arr1 = {1,2,3,4,5,};
int[] arr2 = arr1.clone();
/* 향상된 for문으로 배열 출력하기 */
for(int i : arr2) {
System.out.print(i + " ");
}
System.out.println();
/* 향산된 for문을 이용해 값 증가 시키기 */
for(int i : arr2) {
i +=10;
}
/*증가가 되었는지 출력확인*/
for(int i : arr2) {
System.out.print(i+" ");
//증가되고 있지 않다. 인덱스에 접근해서 값을 변경한게 아니고 꺼낸 값을 복사해서 쓴 것이다.
}
* 주의 : 향상된 for문은 배열에 인덱스에 차례로 접근할 때는 편하게 사용할 수 있지만 값을 변경할 수는 없다.
대신 변경하는 것이 아니고 사용하는 것이 목적이라면 조금 더 편하게 사용할 수 있다.
배열 정렬 ( 순차 정렬 )
값을 서로 변경하기 변수는 하나의 값만 저장 가능 하므로 값을 대입하면 이전의 값은 소멸된다는 점 때문에
임시 변수를 하나 만들어야 기존의 값을 따로 보관하고 대입 작업을 통해 값을 서로 변경할 수 있음
배열도 마찬가지로 이와 같은 원리를 바탕으로 임시 변수를 하나 만들어 서로의 값을 변경할 수 있다.
/*초기 배열 선언 및 초기화*/
int[] iarr = {2,5,4,6,1,3};
/*인덱스를 한개 씩 증가시키는 반복문
* 첫번째 인덱스는 비교할 필요가 없어서 1번 인덱스부터 비교시작*/
for (int i = 1; i < iarr.length; i++) {
/*인덱스가 증가할 때 마다 처음부터 해당 인덱스 -1 까지의 값을 비교하는 반복문 */
for(int j =0; j < i ; j ++) {
/*오름차순 정렬을 위한 처리*/
/*내림차순은 부등호 방향을 반대로 처리*/
if(iarr[i] < iarr[j]) {
/*값 위치 변경 */
int temp;
temp = iarr[i];
iarr[i] = iarr[j];
iarr[j] = temp;
}
}
}
/*결과출력*/
for (int i = 0; i < iarr.length; i++) {
System.out.print(iarr[i] + " ");
}
}
}
Arrays.sort() 방식으로도 정렬해보자.
/*copy 배열*/
int[] copy = iarr.clone();
Arrays.sort(copy);
System.out.println("copy : " + Arrays.toString(copy));
'백엔드 과정 > Java' 카테고리의 다른 글
Java 문제풀이. 랜덤한 로또번호 중복없이 오름차순 정렬하기 (0) | 2021.12.31 |
---|---|
[Java] day10. 클래스와 객체 / 캡슐화 / 생성자 (0) | 2021.12.29 |
Java 문제풀이 4-4. 학생들 분단 나누기. 다차원 배열 문제 (0) | 2021.12.27 |
Java 문제풀이 4-3. 이차원 배열로 랜덤 영문자 출력하기. (0) | 2021.12.27 |
Java 문제풀이 4-2. 주민등록번호 뒷자리 숨기기 (0) | 2021.12.27 |