본문 바로가기
  • 꾸준히 앞으로
언어 log/Java

[Java] Array copy 배열 복사/복제

by lijly 2020. 5. 31.

 

 

[얕은 복사] 주소값 복사


1. B = A;

예시

class Main {
  public static void main(String[] args) {
    int a[] = {1, 8, 3}; 
    int b[] = a;     

    b[0] = 10; 

    // 결과 확인
    System.out.print("a Array : "); 
    for (int v:a) 
        System.out.print(v + " "); 

    System.out.print("\nb Array : "); 
    for (int v:b) 
        System.out.print(v + " "); 
  }
}

 

결과

👉🏽
a Array : 10 8 3
b Array : 10 8 3

 

[깊은 복사] 복제. 새로운 메모리 공간에 값 복사


2. B = A.clone();

예시

class Main {
  public static void main(String[] args) {
    int a[] = {1, 8, 3}; 
    int b[] = a.clone();     

    b[0] = 10; 

    // 결과 확인
    System.out.print("a Array : "); 
    for (int v:a) 
        System.out.print(v + " "); 

    System.out.print("\nb Array : "); 
    for (int v:b) 
        System.out.print(v + " "); 
  }
}

 

결과

👉🏽
a Array : 1 8 3
b Array : 10 8 3

 

3. 기존 배열의 일부만 덮어씌우기 || clone()보다 더 빠르길 원할 때

System.arraycopy()는 Java Native Interface를 사용하기 때문에 clone()보다 더 빠릅니다.

System.arraycopy( A, sourcePos, B, destPos, len );

  • Object A : 복사할 대상
  • int sourcePos : 복사할 배열(A)의 시작 index
  • Object B : 복사될 곳
  • int destPos : 복사될 곳(B)의 시작 index
  • int len : 복사할 길이(원소 개수)

예시

class Main {
  public static void main(String[] args) {
    int a[] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}; 
    int b[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 

    int sourcePos, destPos, len; 
    sourcePos = 3; 
    destPos = 5; 
    len = 4; 

    System.arraycopy(a, sourcePos, b, destPos, len); 
    b[6] = -1;

    // 결과 확인
    System.out.print("a array : "); 
    for (int v:a) 
        System.out.print(v + " "); 
        
    System.out.print("\nb array : "); 
    for (int v:b) 
        System.out.print(v + " "); 
  }
}

 

결과

👉🏽
a array : 10 20 30 40 50 60 70 80 90 100
b array : 0 1 2 3 4 40 -1 60 70 9
  1. b 배열의 index=5부터 a 배열의 index=3을 4개 가져와 덮어씌움
  1. b 배열에 index=6을 -1로 수정

→ 복사한 값을 수정해도 원본 값이 수정되지 않는다.

 

4. 원하는 길이 설정

B = Arrays.copyOf( A, newLength );

  • int[] A : 복사할 배열
  • int newLength : 새로 만들 배열(b)의 길이

예시

import java.util.Arrays;
class Main {
  public static void main(String[] args) {
    int[] a = new int[] {1, 2 ,3}; 
    int[] b = Arrays.copyOf(a, 5); 
    b[0] = 10;

    // 결과 확인
    System.out.print("a Array : "); 
    for (int v:a) 
      System.out.print(v + " "); 

    System.out.print("\nb Array : "); 
    for (int v:b)  
      System.out.print(v + " "); 
    
  }
}

 

결과

👉🏽
a Array : 1 2 3
b Array : 10 2 3 0 0
  1. a 배열을 복사할 때 b 배열 길이를 5로 지정
  1. b 배열에서 index=0인 값을 10으로 수정

→ a 배열 복사 후 남은 공간은 '0'으로 초기화

→ 복사한 값을 수정해도 원본 값이 수정되지 않는다.

 

5. 원하는 시작점 설정

copyOf()는 무조건 index=0에서부터 복사되지만 copyOfRange()는 시작점을 설정할 수 있다.

B = Arrays.copyOfRange( A, from_index, to_index );

  • int[] A : 복사할 배열
  • int from_index : 복사할 배열의 시작 index
  • int to_index : 복사할 배열의 끝 index

    → from_index=1부터 3개를 복사하고 싶다면, to_index = 4

    → to_index가 복사할 배열(A)의 길이를 넘는다면, 0으로 초기화되어 들어간다.

예시

import java.util.Arrays;
class Main {
  public static void main(String[] args) {
    int arr[] = { 0, 1, 2, 3, 4, 5, 6 }; 
  
    // to index is within the range 
    int[] copy1 = Arrays.copyOfRange(arr, 2, 6); 
    
    // 결과 확인
    System.out.print("copy v1 array : "); 
    for (int i : copy1) 
        System.out.print(i + "  "); 

    // to index is out of range 
    // It assigns Zero to all the index out of range 
    int[] copy2 = Arrays.copyOfRange(arr, 4, arr.length + 3); 

    // 결과 확인
    System.out.print("\ncopy v2 array : "); 
    for (int i : copy2) 
        System.out.print(i + "  "); 

    // It throws IIlegalArgumentException 
    // int[] copy2 = Arrays.copyOfRange(arr, 5, 3); 

    // It throws ArrayIndexOutOfBoundsException 
    // int[] copy2 = Arrays.copyOfRange(arr, 10, arr.length + 5);

  }
}

 

결과

👉🏽
copy v1 array : 2 3 4 5
copy v2 array : 4 5 6 0 0 0
  1. arr 배열의 index=2부터 index=6앞까지 가져와 copy1 배열을 만든다.
  1. arr 배열의 index=4부터 index=7+3=10앞까지 가져오는데, arr길이는 7이므로 나머지 3개는 0으로 초기화하여 copy2 배열을 만든다.

 

 

[깊은 복사] 2차원 배열 👀


2차원 배열은 단순 clone()으로 깊은 복사가 되지 않기 때문에 직접 코드를 짜야한다.

예시

class Main {
  public static void main(String[] args) {
    int[][] arr = {{ 10, 11, 12},
                { 13, 14, 15}, 
                { 16, 17, 18}}; 
  
    int[][] copy1 = arr.clone(); 
    
    copy1[1][1] = -1;

    // 결과 확인
    System.out.println("origin              copy v1"); 
    showChangedArr(arr, copy1);

    System.out.println(); 
    int[][] arr2 = {{ 20, 21, 22},
                { 23, 24, 25}, 
                { 26, 27, 28}}; 
    int[][] copy2 = deepCopy(arr2); 

    copy2[1][1] = -1;

    // 결과 확인
    System.out.println("origin              copy v2"); 
    showChangedArr(arr2, copy2);
  }

	// 2차원배열 deep copy 함수
  static int[][] deepCopy(int[][] arr){
    int[][] result = new int[arr.length][arr[0].length];
    for (int i=0; i<arr.length; i++) {
      result[i] = arr[i].clone();
    }
    return result;
  }

  static void showChangedArr(int[][] arr, int[][] arr2){
    for (int i=0; i<arr.length; i++) {
      for(int j=0; j<arr[0].length; j++)
        System.out.printf("%3d ", arr[i][j]); 
      System.out.print("        "); 
      for(int j=0; j<arr2[0].length; j++)
        System.out.printf("%3d ", arr2[i][j]); 
      System.out.println();
    }
  }
}

 

결과

👉🏽
origin      copy v1
10 11 12     10 11 12
13 -1 15     13 -1 15
16 17 18     16 17 18

origin      copy v2
20 21 22     20 21 22
23 24 25     23 -1 25
26 27 28     26 27 28
  1. cone()을 사용하면 1차원 배열과는 달리 깊은 복사가 되지 않는다.
  1. 반복문을 통해 직접 clone() 해주었다. 값을 변경해도 원래 값이 변경되지 않는다.
    • 위에 소개한 다른 메소드를 사용해서 복사해 주어도 된다.

 

 

 

'언어 log > Java' 카테고리의 다른 글

[Java] JVM(Java Virtual Machine) 구조  (0) 2020.09.10
[Java] Array to List, List to Array  (0) 2020.06.13

댓글