Java를 다루다 보면 배열을 복사해야 하는 경우가 있습니다. 이를 위해 자바는 유용한 메서드 중 하나로 사용할 수 있는 메서드가 바로 copyOf(), arraycopy(), copyOfRange() 메서드입니다.
위 Arrays 클래스 메서드들은 java.util 패키지에 포함되어 있으므로 메서드를 사용하기 위해서는 다음의 import가 필요합니다.
import java.util.Arrays;
이 글에서는 copyOf(), arraycopy(), copyOfRange() 메서드의 기능과 사용법, 그리고 실제 예제를 통해 그 활용 방법을 자세히 살펴보겠습니다.
copyOf()란❓
public static <T> T[] copyOf(T[] original, int newLength)
Arrays.copyOf() 메서드는 Java에서 배열을 복사하고 새로운 배열을 생성하는 유틸리티 메서드입니다.
지정한 배열을 인덱스 0부터 원하는 길이만큼 복사를 합니다.
- original
- 복사할 원본 배열입니다.
- newLength
- 새로 생성될 배열의 길이를 나타냅니다. 이 길이가 원본 배열보다 크면, 나머지 요소는 해당 배열 요소의 기본값으로 채워집니다
copyOf()의 특징과 장단점
특징
- 원본 배열의 타입과 동일한 타입의 새로운 배열을 생성합니다.
- 길이를 조정하여 배열을 복사하거나 확장할 수 있습니다.
- 복사된 배열은 원본 배열의 요소를 유지하며, 추가된 부분은 기본값으로 초기화됩니다.
장점
- 간단하게 배열을 복사하거나 길이를 조정할 수 있습니다.
- 제네릭으로 선언되어 여러 타입의 배열에 대해 일반적으로 사용할 수 있습니다.
단점
- 배열의 크기를 변경할 때, 추가된 부분은 기본값으로 채워지므로 초기화가 필요할 수 있습니다.
copyOf() 예제
import java.util.Arrays;
public class ArrayCopyExample {
public static void main(String[] args) {
// 정수형 배열 복사 예제
int[] originalIntArray = {1, 2, 3, 4, 5};
int[] copiedIntArray = Arrays.copyOf(originalIntArray, 7); // 길이가 7인 새로운 배열 생성, 나머지 요소는 기본값으로 초기화됨
System.out.println("Copied Int Array: " + Arrays.toString(copiedIntArray)); // [1, 2, 3, 4, 5, 0, 0]
// 문자열 배열 복사 예제
String[] originalStringArray = {"apple", "banana", "cherry"};
String[] copiedStringArray = Arrays.copyOf(originalStringArray, 5); // 길이가 5인 새로운 배열 생성, 나머지 요소는 기본값(null)으로 초기화됨
System.out.println("Copied String Array: " + Arrays.toString(copiedStringArray)); // [apple, banana, cherry, null, null]
}
}
Copied Int Array: [1, 2, 3, 4, 5, 0, 0]
Copied String Array: [apple, banana, cherry, null, null]
이와 같이 Arrays.copyOf() 메서드는 배열의 복사뿐만 아니라, 배열의 길이를 조정하여 새로운 배열을 생성할 때 유용하게 사용될 수 있습니다.
◼ 정수형 타입
➡ byte: 0 short: 0 int: 0 long: 0 Lchar: '\u0000' (널 문자)
◼ 부동소수점 타입
➡ float: 0.0 fdouble: 0.0d
◼ 불리언 타입
➡ boolean: false
◼ 참조 타입
➡ 모든 참조 타입의 기본값은 null입니다.
System.arraycopy()란❓
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
System.arraycopy() 메서드는 Java에서 배열을 복사하는 메서드입니다. 이 메서드는 네이티브 메서드로 구현되어 있어서, 배열 복사 작업을 매우 효율적으로 처리할 수 있습니다.
- src
- 복사할 원본 배열입니다.
- srcPos
- 원본 배열에서 복사를 시작할 인덱스입니다.
- dest
- 복사할 대상 배열입니다.
- destPos
- 대상 배열에서 복사를 시작할 인덱스입니다.
- length
- 복사할 요소의 개수입니다.
System.arraycopy() 특징과 장단점
특징
- 원본 배열의 특정 부분을 대상 배열로 복사할 수 있습니다.
- 배열의 일부분만 복사할 수 있고, 다차원 배열에서도 사용할 수 있습니다.
- 네이티브 메서드로 구현되어 있어서 성능이 매우 우수합니다.
장점
- 배열 복사 작업을 매우 빠르고 효율적으로 처리할 수 있습니다.
- 다차원 배열에서도 사용할 수 있어 유연성이 있습니다.
단점
- 인덱스가 범위를 벗어날 경우 ArrayIndexOutOfBoundsException이 발생할 수 있습니다.
- 복사할 요소의 개수가 원본 배열과 대상 배열의 길이보다 길면 예외가 발생합니다.
System.arraycopy()의 예제
public class ArrayCopyExample {
public static void main(String[] args) {
// 원본 배열
int[] srcArray = {1, 2, 3, 4, 5};
// 대상 배열 생성 (길이는 원본 배열과 동일하게)
int[] destArray = new int[srcArray.length];
// srcArray의 인덱스 1부터 시작하여 destArray의 인덱스 0부터 3개의 요소를 복사
System.arraycopy(srcArray, 1, destArray, 0, 3);
// 결과 출력
System.out.println("Copied Array: " + Arrays.toString(destArray)); // 출력: [2, 3, 4, 0, 0]
}
}
예외 발생 예제
public class ArrayCopyErrorExample {
public static void main(String[] args) {
int[] srcArray = {1, 2, 3, 4, 5};
int[] destArray = new int[3]; // 작은 크기로 초기화
// 배열 길이가 다를 때 복사 시도
System.arraycopy(srcArray, 0, destArray, 0, srcArray.length);
System.out.println("Copied Array: " + Arrays.toString(destArray));
}
}
- srcArray의 길이는 5이지만, destArray의 길이는 3으로 작아서 System.arraycopy() 메서드가 복사할 수 있는 범위를 벗어납니다.
- 따라서 ArrayIndexOutOfBoundsException이 발생합니다.
예외 처리 예제
public class ArrayCopyExample {
public static void main(String[] args) {
int[] srcArray = {1, 2, 3, 4, 5};
int[] destArray = new int[5]; // 충분한 크기로 초기화
// 배열 길이가 같을 때만 복사하도록 사전 조건 검사
if (srcArray.length == destArray.length) {
System.arraycopy(srcArray, 0, destArray, 0, srcArray.length);
System.out.println("Copied Array: " + Arrays.toString(destArray));
} else {
System.out.println("Arrays have different lengths, copy aborted.");
}
}
}
- destArray를 충분한 크기로 초기화하여 System.arraycopy() 메서드가 복사를 수행할 수 있도록 합니다.
- srcArray와 destArray의 길이를 먼저 비교하여 같을 때만 복사를 시도하도록 사전 조건을 검사합니다.
- 이렇게 하면 배열 길이의 불일치로 인한 예외를 방지할 수 있습니다.
copyOfRange() 란❓
public static <T> T[] copyOfRange(T[] original, int from, int to)
copyOfRange() 메서드는 Java에서 배열의 일부분을 복사하여 새로운 배열을 생성하는 유틸리티 메서드입니다.
- original
- 복사할 원본 배열입니다.
- from
- 복사를 시작할 인덱스입니다 (이 인덱스를 포함합니다).
- to
- 복사를 종료할 인덱스입니다 (이 인덱스를
포함하지 않음).
- 복사를 종료할 인덱스입니다 (이 인덱스를
copyOfRange()의 특징과 장단점
- from 인덱스부터 to-1 인덱스까지의 배열 요소를 복사하여 새로운 배열을 생성합니다.
- 복사할 범위가 원본 배열의 길이를 초과하지 않아야 합니다. 그렇지 않으면 ArrayIndexOutOfBoundsException이 발생할 수 있습니다.
- 복사된 배열의 길이는 to - from입니다.
- 원본 배열과 동일한 타입의 배열이 반환됩니다.
copyOfRange()의 예제
예외 발생 예제
import java.util.Arrays;
public class CopyOfRangeExceptionExample {
public static void main(String[] args) {
Integer[] originalArray = {1, 2, 3, 4, 5};
// 인덱스 범위를 벗어나는 복사 시도 (ArrayIndexOutOfBoundsException 발생)
Integer[] copiedArray = Arrays.copyOfRange(originalArray, 2, 7); // to가 범위를 벗어남
System.out.println("Copied Array: " + Arrays.toString(copiedArray));
}
}
Arrays.copyOfRange(originalArray, 2, 7)은 originalArray 배열에서 인덱스 2부터 6까지의 요소를 복사하려고 시도합니다.
하지만 originalArray의 길이는 5이므로, 인덱스 범위를 벗어나기 때문에 ArrayIndexOutOfBoundsException이 발생합니다.
예외 처리 예제
import java.util.Arrays;
public class CopyOfRangePreventionExample {
public static void main(String[] args) {
Integer[] originalArray = {1, 2, 3, 4, 5};
// 복사할 범위를 사전에 검사하여 예외를 방지
int from = 2;
int to = 4;
if (from >= 0 && to <= originalArray.length && from < to) {
Integer[] copiedArray = Arrays.copyOfRange(originalArray, from, to);
System.out.println("Copied Array: " + Arrays.toString(copiedArray));
} else {
System.out.println("Invalid range specified, copy aborted.");
}
}
}
- from과 to 인덱스를 사전에 검사하여 배열의 범위를 벗어나지 않도록 조건을 설정합니다.
- from이 0 이상이고, to가 originalArray.length 이하이며, from이 to보다 작은 경우에만 복사를 시도합니다.
- 이렇게 하면 Arrays.copyOfRange() 메서드에서 발생할 수 있는 ArrayIndexOutOfBoundsException을 방지할 수 있습니다.
parseInt() 란❓
parseInt(String s)
- parseInt(String s): 10진수 문자열을 정수로 변환합니다.
parseInt(String s, int radix)
- parseInt(String s, int radix) :특정 진법(radix)의 문자열을 10진수 정수로 변환합니다. radix는 2(이진법)에서 36진법까지의 값을 가질 수 있습니다.
반대로 10진수 정수를 2진수로 변환하는 방법은 parseInt() 메서드를 사용하면 됩니다.
parseInt() 메서드는 문자열을 정수로 변환하는 데 사용되며, 특정 진법의 문자열을 10진수 정수로 변환할 수 있는 기능을 제공합니다.
parseInt()의 예제
10진수 문자열을 정수로 변환
public class ParseIntExample {
public static void main(String[] args) {
String numberStr = "123";
int number = Integer.parseInt(numberStr);
System.out.println("변환된 정수: " + number);
}
}
// 결과 : 변환된 정수: 123
2진수 문자열을 정수로 변환
public class ParseIntExample {
public static void main(String[] args) {
String binaryStr = "1101";
int number = Integer.parseInt(binaryStr, 2);
System.out.println("2진수 1101의 10진수 표현: " + number);
}
}
// 결과 : 2진수 1101의 10진수 표현: 13
16진수 문자열을 정수로 변환
public class ParseIntExample {
public static void main(String[] args) {
String hexStr = "1A3F";
int number = Integer.parseInt(hexStr, 16);
System.out.println("16진수 1A3F의 10진수 표현: " + number);
}
}
// 결과 : 16진수 1A3F의 10진수 표현: 6719
장점
- 다양한 진법 지원: 2진수부터 36진수까지 다양한 진법의 문자열을 10진수 정수로 변환할 수 있습니다.
- 표준 예외 처리: 변환 중 숫자 형식이 잘못된 경우 NumberFormatException을 던지므로 오류를 쉽게 처리할 수 있습니다.
- 간단하고 사용하기 쉬움: 단순한 메서드 호출로 문자열을 정수로 변환할 수 있어 코드가 간결해집니다.
단점
- 예외 처리 필요: 입력 문자열이 유효하지 않거나 지정된 진법에 맞지 않으면 NumberFormatException이 발생하므로 반드시 예외 처리가 필요합니다.
- 제한된 진법 범위: radix 값은 2에서 36까지만 지원되므로 이 범위를 벗어나는 경우 변환할 수 없습니다.
예외 처리 예제
public class ParseIntExample {
public static void main(String[] args) {
String invalidNumberStr = "123a";
try {
int number = Integer.parseInt(invalidNumberStr);
System.out.println("변환된 정수: " + number);
} catch (NumberFormatException e) {
System.out.println("잘못된 숫자 형식: " + invalidNumberStr);
}
}
}
// 결과 : 잘못된 숫자 형식: 123a
위와 같이 parseInt 메서드는 문자열을 정수로 변환할 때 매우 유용합니다. 특히 다양한 진법의 문자열을 처리할 수 있어, 여러 상황에서 활용될 수 있습니다. 예외 처리를 적절히 하면 더욱 안정적으로 사용할 수 있습니다.
정리 ✅
- Arrays.copyOf()를 고려
- 전체 배열을 복사하거나,
복사 대상의 객체를 변경하지 않아도 되는 경우 Arrays.copyOf()를 사용..
- 전체 배열을 복사하거나,
- System.arraycopy()를 고려
- 복사할 길이를 명시적으로 지정하거나 복사할 객체를 유지해야 하는 경우 System.arraycopy()를 사용.
- Arrays.copyOfRange()를 고려
- 일부분을 빠르게 복사하거나, 기존 배열을 일정 범위로 복사할 때 Arrays.copyOfRange()를 사용
'Language > Java' 카테고리의 다른 글
[JAVA] 람다 표현식을 활용한 정렬 기법: 오름차순과 내림차순 (1차원, 2차원) (0) | 2024.07.10 |
---|---|
[JAVA] 좌표와 2차원 배열 매핑의 이해 (좌표 ➡️ 배열) (0) | 2024.07.01 |
[Java] toBinaryString(), toHexString(), toOctalString() , parseInt() 알아보기 (n진법 변환) (1) | 2024.06.09 |
[JAVA] Character.isLetter() & Character.isDigit() 메서드 알아보기 (1) | 2024.06.04 |
[JAVA] 더블 콜론 연산자 :: 알아보기 (메서드 참조 사용 방법과 예제) (0) | 2024.06.02 |