Java/배열

[Java]배열 복사하는 방법

DevStory 2022. 8. 22.

배열 복사하는 방법

Java에서 배열은 기본 타입이 아닌 참조 타입입니다. 따라서, 배열의 실제 데이터는 Heap 영역에 생성되고 변수는 Stack 영역에 생성됩니다.

 

Stack 영역에 생성된 변수는 참조 값(Heap 영역에 생성된 실제 데이터의 위치)을 통해 배열의 데이터를 접근합니다. 만약, 참조 값을 다른 변수에 할당하는 경우 두 개 이상의 변수가 Heap 영역에 생성된 실제 데이터를 조작할 수 있습니다.

 

예를 들어, 다음 소스 코드처럼 배열 변수를 다른 변수에 할당 후 값을 변경하면 참조 값을 공유하므로 원본 데이터가 보존되지 않는 문제가 발생합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray = originArray;

  System.out.println("[변경 전]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[변경 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[변경 전]
originArray: [AA, BB, CC, DD]
copiedArray: [AA, BB, CC, DD]

[변경 후]
originArray: [EE, BB, CC, DD]
copiedArray: [EE, BB, CC, DD]

따라서, 배열 변수를 다른 변수에 할당하는 방법은 원본 데이터가 변경될 수 있으므로 배열을 복사하는 방법으로 적절하지 않습니다.

 

이번 포스팅은 배열을 복사할 수 있는 몇 가지 방법을 소개합니다.

 

아래 방법들을 사용하면, 참조 값을 공유하지 않으므로 원본 데이터를 보존할 수 있습니다.


방법 1. 반복문

가장 심플한 방법으로 반복문을 사용합니다.

 

[복사 방법]

순서 1. 원본 배열의 요소 개수를 새로운 배열의 크기로 설정합니다.

순서 2. 반복문을 사용하여 원본 배열의 값을 새로운 배열에 할당합니다.

 

다음 예제는 for문을 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 문자열 "EE"로 변경합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray = new String[originArray.length];

  System.out.println("[변경 전]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  for (int index = 0; index < originArray.length; index++) {
    copiedArray[index] = originArray[index];
  }

  System.out.println("\n[복사 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[copiedArray의 0번째 위치 값을 \"EE\"로 변경]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[변경 전]
originArray: [AA, BB, CC, DD]
copiedArray: [null, null, null, null]

[복사 후]
originArray: [AA, BB, CC, DD]
copiedArray: [AA, BB, CC, DD]

[copiedArray의 0번째 위치 값을 "EE"로 변경]
originArray: [AA, BB, CC, DD]
copiedArray: [EE, BB, CC, DD]

방법 2. System 클래스의 arraycopy 메서드

두 번째 방법으로 System 클래스에서 제공하는 arraycopy() 메서드를 사용하여 배열을 복사할 수 있습니다.

 

[복사 방법]

순서 1. 원본 배열의 요소 개수를 새로운 배열의 크기로 설정합니다.

순서 2. System 클래스의 arraycopy() 메서드를 호출하고 원본 배열, 새로운 배열, 복사 시작 위치, 복사하려는 데이터 개수를 매개변수로 전달합니다.

 

다음 예제는 arraycopy() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 문자열 "EE"로 변경합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray = new String[originArray.length];

  System.out.println("[변경 전]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  System.arraycopy(originArray, 0, copiedArray, 0, originArray.length);

  System.out.println("\n[복사 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[copiedArray의 0번째 위치 값을 \"EE\"로 변경]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[변경 전]
originArray: [AA, BB, CC, DD]
copiedArray: [null, null, null, null]

[복사 후]
originArray: [AA, BB, CC, DD]
copiedArray: [AA, BB, CC, DD]

[copiedArray의 0번째 위치 값을 "EE"로 변경]
originArray: [AA, BB, CC, DD]
copiedArray: [EE, BB, CC, DD]

방법 3. Arrays 클래스의 copyOf 메서드

세 번째 방법으로 Arrays 클래스의 copyOf() 메서드를 사용하여 배열을 복사할 수 있습니다. copyOf() 메서드는 복사된 새로운 배열을 반환하며, 내부적으로 System 클래스의 arraycopy() 메서드를 호출합니다.

 

매개변수로 원본 배열과 새로 생성할 배열의 크기를 전달합니다.

 

다음 예제는 copyOf() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 문자열 "EE"로 변경합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray = Arrays.copyOf(originArray, originArray.length);

  System.out.println("[복사 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[copiedArray의 0번째 위치 값을 \"EE\"로 변경]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[복사 후]
originArray: [AA, BB, CC, DD]
copiedArray: [AA, BB, CC, DD]

[copiedArray의 0번째 위치 값을 "EE"로 변경]
originArray: [AA, BB, CC, DD]
copiedArray: [EE, BB, CC, DD]

방법 4. Arrays 클래스의 copyOfRange 메서드

네 번째 방법으로 Arrays 클래스의 copyOfRange() 메서드를 사용할 수 있습니다.

 

copyOfRange() 메서드는 원본 배열에서 특정 범위(시작 인덱스 ~ 종료 인덱스)에 포함되는 값을 복사합니다.

 

다음 예제는 원본 배열의 1번째 인덱스부터 마지막 위치까지 복사 후 새로운 배열 0번째 위치의 값을 문자열 "EE"로 변경합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray = Arrays.copyOfRange(originArray, 1, originArray.length);

  System.out.println("[복사 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[copiedArray의 0번째 위치 값을 \"EE\"로 변경]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[복사 후]
originArray: [AA, BB, CC, DD]
copiedArray: [BB, CC, DD]

[copiedArray의 0번째 위치 값을 "EE"로 변경]
originArray: [AA, BB, CC, DD]
copiedArray: [EE, CC, DD]

방법 5. Object 클래스의 clone 메서드

Object 클래스의 clone() 메서드를 사용하여 배열을 복제할 수 있습니다.

 

다음 예제는 clone() 메서드를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 문자열 "EE"로 변경합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray =  originArray.clone();

  System.out.println("[복사 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[copiedArray의 0번째 위치 값을 \"EE\"로 변경]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[복사 후]
originArray: [AA, BB, CC, DD]
copiedArray: [AA, BB, CC, DD]

[copiedArray의 0번째 위치 값을 "EE"로 변경]
originArray: [AA, BB, CC, DD]
copiedArray: [EE, BB, CC, DD]

방법 6. Stream API

Java 버전이 1.8 이상인 경우 Stream API를 사용하여 배열을 복사할 수 있습니다.

 

원본 배열을 스트림으로 변환 후 toArray() 메서드를 호출하여 새로운 배열을 생성합니다.

 

다음 예제는 Stream API를 사용하여 배열을 복사 후 새로운 배열 0번째 위치의 값을 문자열 "EE"로 변경합니다.

public static void main(String args[]) {
  String[] originArray = { "AA", "BB", "CC", "DD" };
  String[] copiedArray =  Arrays.stream(originArray).toArray(String[]::new);

  System.out.println("[복사 후]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));

  copiedArray[0] = "EE";

  System.out.println("\n[copiedArray의 0번째 위치 값을 \"EE\"로 변경]");
  System.out.println("originArray: " + Arrays.toString(originArray));
  System.out.println("copiedArray: " + Arrays.toString(copiedArray));
}

[실행 결과]

[복사 후]
originArray: [AA, BB, CC, DD]
copiedArray: [AA, BB, CC, DD]

[copiedArray의 0번째 위치 값을 "EE"로 변경]
originArray: [AA, BB, CC, DD]
copiedArray: [EE, BB, CC, DD]
반응형

댓글