[Java] copy(배열의 복사)

Date:     Updated:

카테고리:

태그:

java.png

배열의 복사

  • 배열의 복사에는 두 종류가 있다
  1. 얕은 복사 : stack 의 주소값만 복사
  2. 깊은 복사 : heap 의 배열에 저장한 값을 복사
  • 얕은 복사는 stack 에 저장되어 있는 배열의 주소값만 복사한다는 것이다
  • 따라서 두 개의 래퍼런스 변수는 동일한 배열의 주소값을 가지고 있다
  • 하나의 래퍼런스 변수에 저장된 주소값을 가지고 배열의 내용을 수정(값 변경)을 하게되면
  • 다른 래퍼런스 변수로 배열에 접근했을 때도 동일한 배열을 가르키고 있기 때문에 변경된 값이 반영되었다
package section03.copy;

public class Application1 {

    public static void main(String[] args) {
      
        int[] originArr = {1, 2, 3, 4, 5};

        int[] copy = originArr;         // 얕은 복사

        System.out.println("originArr = " + originArr.hashCode());
        System.out.println("copy = " + copy.hashCode());

        for (int i = 0; i < originArr.length; i++) {
            System.out.print(originArr[i] + " ");
        }
        System.out.println();

        for (int i = 0; i < originArr.length; i++) {
            System.out.print(copy[i] + " ");
        }
        System.out.println();

    }
}
  • 출력값
originArr = 1283928880
copy = 1283928880
1 2 3 4 5 
1 2 3 4 5 

얕은 복사를 활용하여 매개변수와 리턴값으로 활용할 수 있다

얕은 복사의 활용

  • 얕은 복사를 활용하는 것은 주로 메소드 호출시 인자로 사용하는 경우와
  • 리턴값으로 동일한 배열을 리턴해주고 싶은 경우 사용한다
package section03.copy;

public class Application2 {

    public static void main(String[] args) {
        
        String[] name = {"홍길동", "유관순", "이순신"};

        System.out.println("name.hashCode() = " + name.hashCode()); //1283928880

        /* 1. 인자와 매개변수로 활용 */
        print(name);

        /* 2. 리턴값으로 활용 */
        String[] animals = getAnimals();

        System.out.println("리턴 받은 animals.hashcode() =  " + animals.hashCode());

        print(animals); // 1989780873
    }

    public static void print(String[] sarr) {

        System.out.println("sarr.hashCode() = " + sarr.hashCode()); // 1283928880
        for (int i = 0; i < sarr.length; i++) {
            System.out.print(sarr[i] + " ");
        }
        System.out.println();
    }

    public static String[] getAnimals() {

        String[] animals = new String[] {"뱀", "판다", "다람쥐"};

        System.out.println("새로만든 animals의 hashcode = " + animals.hashCode());

        return animals;
    }
}
  • 출력값
name.hashCode() = 1283928880
sarr.hashCode() = 1283928880
홍길동 유관순 이순신 
새로만든 animals의 hashcode = 1989780873
리턴 받은 animals.hashcode() =  1989780873
sarr.hashCode() = 1989780873
뱀 판다 다람쥐 

깊은 복사에 대해 이해할 수 있다

  • 깊은 복사는 heap 에 생성된 배열이 가지고 있는 값을
  • 또 다른 배열에 복사를 해놓은 것이다
  • 서로 같은 값을 가지고 있지만, 두 배열은 서로 다른 배열이기 때문에
  • 하나의 배열을 변경 하더라도 다른 배열에는 영향을 주지 않는다

깊은 복사를 하는 방법은 4가지가 있다

  1. for 문을 이용한 동일한 인덱스 값 복사
  2. Object 의 clone()을 이용한 복사
  3. System의 arraycopy()를 이용한 복사
  4. Array의 copyOf()를 이용한 복사
  • 이중에서 가장 높은 성능을 보이는 것은 순수 배열의 복사를 위해 만들어진 arraycopy()메소드이며,
    • 가장 많이 사용되는 방식은 좀 더 유연한 방식인 copyOf() 메소드이다
    • clone()은 이전 배열과 같은 배열밖에 만들 수 없다는 특징을 가지고
    • 그 외 3가지 방법은 복사하는 길이의 배열의 길이를 마음대로 조절할 수 있다는 특징을 가지고 있다
package section03.copy;

import java.util.Arrays;

public class Application3 {

    public static void main(String[] args) {

        int[] originArr = new int[]{1, 2, 3, 4, 5}; //1283928880

        print(originArr);

        /*1. for문을 통해서 동일한 인덱스 값 복사 */
        int[] copyArr = new int[10];

        for(int i = 0; i < originArr.length; i++){
            copyArr[i] = originArr[i];

        }

        print(copyArr);

        /* 2.Object의 clone()을 이용한 복사 */
        int[] copyArr2 = originArr.clone();

        print(copyArr2);

        /* 3. System의 arraycopy()을 이용한 복사 */
        int[] copyArr3 = new int[10]; //81628611
        /* 원본배열. 복사를 시작할 인덱스, 복사할 배열, 복사를 시작할 인덱스, 복사할 길이릐 의미를 가진다. */
        System.arraycopy(originArr,0,copyArr3,3,originArr.length);

        print(copyArr3);

        /* 4.Array의 copyOf()을 이용한 복사 */
        int[] copyArr4 = Arrays.copyOf(originArr,7);

        print(copyArr4);

    }

        public static void print(int[] iarr) {

            System.out.println("iarr.hashCode() = " + iarr.hashCode()); // 1283928880
            for (int i = 0; i < iarr.length; i++) {
                System.out.print(iarr[i] + " ");
            }
            System.out.println();
        }
    }
  • 출력값
iarr.hashCode() = 1283928880
1 2 3 4 5 
iarr.hashCode() = 1989780873
1 2 3 4 5 0 0 0 0 0 
iarr.hashCode() = 1480010240
1 2 3 4 5 
iarr.hashCode() = 81628611
0 0 0 1 2 3 4 5 0 0 
iarr.hashCode() = 1828972342
1 2 3 4 5 0 0 

배열의 깊은 복사를 사용한 자바문법을 이해하고 활용할 수 있다

  • 깊은 복사는 원본과 복사본 중 둘 중 한가지 값을 변경해도 다른 하나에 영향을 주지 않는다
  • 값은 값을 가지고 있는 서로 다른 배열이기 때문이다
package section03.copy;

public class Application4 {

    public static void main(String[] args) {
      
        int[] arr1 = {1,2,3,4,5};
        int[] arr2 = arr1.clone();

        for(int i = 0; i<arr1.length; i++){
            arr1[i] +=10;

        }
        for(int i = 0; i < arr1.length; i++){
            System.out.print(arr1[i] + " ");
        }
        System.out.println();

        /* 향상된 for문 : jdk 1.5버전부터 추가되었다 */
        /*배열 인덱스에 하나씩 차례로 접근해서 담긴 값을 임시로 사용할 변수에 담고 반복문을 실행한다.
        * */

        for(int i : arr2){
            i+=10;
        }
        for(int i = 0; i < arr2.length; i++){
            System.out.print(arr2[i] + " ");
        }
        System.out.println();


    }
}
  • 출력값
11 12 13 14 15 
1 2 3 4 5 

요약. 1. 얕은 복사 : stack의 주소값만 복사 2. 깊은 복사 : heap의 배열에 저장한 값을 복사

조금더 부지런하게 움직이자!!

Java 카테고리 내 다른 글 보러가기

댓글 남기기