코딩테스트를 준비하던 중, 그동안은 유야무야 넘겼던 배열의 복사에 관한 메서드를 쓸 일이 생겼다.
문제를 푸는데는 별 문제가 없었지만, 이 기회에 깊은 복사와 얕은 복사에 대해서 다시 한 번 정확하게 짚고가야 할 것 같다고 생각되어 이 포스트를 작성하게 되었다.
1) 기본 데이터 타입의 필드
int , double , char ...2) 참조 데이터 타입의 필드
String , 배열 , 객체 ...int[] originArr = {1, 2, 3, 4, 5};
int[] copiedArr = originArr;
copiedArr 는 originArr 의 주소를 가리키고 있으므로, originArr 와 copiedArr 의 값이 변경될 시 서로 영향을 받음1) 기본 데이터 타입의 필드
String , 배열 , 객체 ...2) 참조 데이터 타이브이 필드
1) clone()
int[] originArr = {1, 2, 3, 4, 5};
int[] copiedArr = originArr.clone();
2) Arrays.copyOf()
int[] originArr = {1, 2, 3, 4, 5};
int[] copiedArr = Arrays.copyOf(originArr, originArr.length);
3) System.arraycopy()
int[] originArr = {1, 2, 3, 4, 5};
int size = originArr.length; // 배열의 길이
int[] copiedArr = new int[size];
System.arraycopy(originArr, 0, copiedArr, 0, size); // 전체 복사
originArr 의 0번 인덱스부터 size 만큼을 복사해서 copiedArr 의 0번 인덱스부터 붙여넣음originArr 로부터 복사되지 않는 copiedArr 의 요소는 그대로 0ArrayIndexOutOfBoundsException 이 발생| 특징 | 얕은 복사 | 깊은 복사 |
|---|---|---|
| 복사 범위 | 필드 값만 복사, 참조형 필드는 참조 주소만 복사 | 모든 필드와 참조형 객체까지 새로 복사 |
| 참조 공유 여부 | 원본 객체와 복사된 객체가 참조형 필드를 공유 | 원본 객체와 복사된 객체가 독립적 |
| 변경 영향 | 참조형 필드의 변경이 원본과 복사본에 모두 영향을 미침 | 원본과 복사본이 서로 영향을 주지 않음 |
1) 얕은 복사
2) 깊은 복사
두 메서드 모두 배열의 깊은 복사를 하고 싶을 때 사용한다. 그렇다면 성능면에서, 어떤 메서드를 사는 것이 더 좋을까?
System.arraycopy() 를 내부적으로 호출System.arraycopy() 가 조금이라도 더 빠름Arrays.copyOf() 는 내부적으로 System.arraycopy() 를 호출하기 때문System.arraycopy() 는 저수준에서 최적화된 네이티브 코드로 구현되어 있음Arrays.copyof() 를 사용해도 큰 문제가 없음System.arraycopy() 와는 다르게 Arrays.copyof() 는 배열의 크기를 동적으로 조절할 수 있기 때문에, 이런 면에서 더욱 이점이 있음참고) OpenAI. (2024).ChatGPT(4o)[Large language model].https://chatgpt.com/