Programming Language/Java

배열(Array) - 선언과 할당 및 초기화, 복사

Ma_Sand 2022. 2. 24. 19:33
반응형

1. 특징

  - 같은 자료형의 변수를 하나로 묶는다. 즉, 한 공간에 여러 개의 값을 저장할 수 있다.

      cf) 변수: 한 공간의 하나의 값만 저장할 수 있다.

  - 배열의 각 인덱스(index)에 값을 저장할 수 있다.

      ex) int[] : 각 인덱스의 크기는 4 byte

           double[] : 각 인덱스의 크기는 8 byte

  - 배열은 저장된 값마다 인덱스 번호가 0부터 시작된다.

변수와 배열의 공간 비교

 

 

 

2. 배열의 선언과 할당, 초기화

 (1) 배열의 선언

   ① 표현법

     - 자료형[] 배열명;

       자료형 배열명[]; (이 표현은 권장하지 않음)

 

   ② 예시

     - int[] arr

       int arr[]

     - double[] arr

       double arr[]

 

 

 (2) 배열의 할당

   ① 표현법

     - 자료형[] 배열명 = new 자료형[배열크기];

       자료형 배열명[] = new 자료형[배열크기];

 

   ② 예시

     - int[] arr = new int[4];

       int arr[] = new int[4];

     - double[] arr = new double[4];

       double arr[] = new double[4];

 

 

 (3) 선언과 동시에 할당

int[] arr = new int[4];  //4칸 짜리

 

 

 (4) 배열의 초기화

   ① 인덱스를 이용한 초기화

arr[0] = 10;  //0번 인덱스에 값 10을 저장
arr[3] = 40;  //3번 인덱스에 값 40을 저장

 

   ② for문을 이용한 초기화 

for(int i = 0; i < arr.length; i++) {
    arr[i] = i;
}

 

   ③ 선언과 동시에 초기화

int[] arr = {1, 2, 3, 4};
int[] arr = new int[]{1, 2, 3, 4};
String song[] = {"바람이 분다", "분홍신", "떠나간다", "Dynamite"};

 

 

 

3. 배열을 사용하는 이유

// 0에서 4까지 출력한다.
// 변수만을 사용한다면?

int num1 = 0;
int num2 = 1;
int num3 = 2;
int num4 = 3;
int num5 = 4;

// 변수를 일일이 다 입력해야 하는 번거로움이 있다.

 

 

 (1) 예시

//int 배열을 만들어서 값을 넣어 반복문으로 출력하기

int[] arr = new int[3];

arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
arr[3] = 4;

// System.out.println(arr[0]);
// System.out.println(arr[1]);
// System.out.println(arr[2]);        // 이렇게 일일이 작성하기는 번거롭다.
// System.out.println(arr[3]);        // arr[0]~arr[3]을 보면 일정한 패턴이 보인다. -> 반복문 사용

for(int i = 0; i < 3; i++) {          // for문을 사용하니 간단하게 정리가 됐다.
    System.out.println(arr[i]);
}

▼실행결과

1
2
3
4

 

 

 

4. 배열의 복사

 (1) 얕은 복사

    : 객체의 주소값만 가져와서 참조형 변수에 저장하고, 하나의 객체를 두 변수가 참조하는 것이다.

int[] arr1 = new int[5];
int[] arr2 = arr1;

 

public void array() {
    // 기존 배열
    int[] a = new int[4];
    
    for(int i = 0; i < a.length; i++) {
        a[i] += 3 * i;
    }
    System.out.println("===== 기존 배열 =====");
    for(int i = 0; i < a.length; i++) {
        System.out.println(a[i]);
    }
    
    // 배열 복사
    int[] copy = a;
    
    System.out.println("===== 배열 복사 =====");
    for(int i = 0; i < copy.length; i++) {
        System.out.println(copy[i]);
    }
}

기존 배열의 변수를 복사 배열 변수에 대입한다. 그러면 이 두 변수들은 하나의 객체를 참조하게 된다.

▼실행결과

===== 기존 배열 =====
0
3
6
9
===== 배열 복사 =====
0
3
6
9

 

 

 (2) 깊은 복사

    : 새로운 배열 객체를 생성하여 기존 배열의 데이터를 복사하는 것이다.

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

System.arraycopy(arr1, 0, arr2, 0, arr1.length);

arr2 = Arrays.copyOf(arr1, arr1.length);

arr2 = arr1.clone();

 

   ① System.arraycopy()

int[] origin = {1, 2, 3, 4, 5, 6};
int[] copy = new int[6];

// System.arraycopy(원본 배열, 원본 배열 시작 위치(인덱스), 복사 배열, 복사 배열 시작 위치(인덱스), 복사할 길이);
System.arraycopy(origin, 0, copy, 0, 4);

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

     - 원본 배열명: origin

     - 원본 배열 시작 위치(인덱스): 0 (인덱스 0번, 원본 배열의 0번째 인덱스값부터 시작)

     - 복사 배열명: copy

     - 복사 배열 시작 위치(인덱스): 0 (인덱스 0번, 원본 배열의 0번째 인덱스값을 복사 배열의 0번째 인덱스부터 복사)

     - 복사할 길이: 4 (복사 배열 시작 위치인 복사 배열의 0번째 인덱스부터 복사 배열의 4번째 인덱스까지 복사)

▼실행결과

1 2 3 4 0 0

복사하지 않은 값은 기본값인 0으로 출력된다.

 

위의 조건으로 System.arraycopy(origin, 0 , copy, 0, 4);를 System.arraycopy(origin, 1, copy, 3, 3);로 바꿔서 다시 실행해보겠다.

int[] origin = {1, 2, 3, 4, 5, 6};
int[] copy = new int[6];

System.arraycopy(origin, 1, copy, 3, 3);

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

▼실행결과

0 0 0 2 3 4

원본 배열의 1번째 인덱스부터의 값이 '2, 3, 4, 5, 6'이다. 그런데 복사 배열 시작은 3번째 인덱스부터이므로 복사 배열의 0~2번째 인덱스에는 아무 것도 저장되지 않아 0으로 출력이 된다. 그러면 '0, 0, 0, 2, 3, 4, 5, 6'이어야 하는데, copy에 할당된 값은 6이고 복사할 길이도 3이므로, 복사 배열의 3번째, 4번째, 5번째 인덱스까지만 출력이 되어 위의 실행결과처럼 '0, 0, 0, 2, 3, 4'가 출력된다.

여기서 만약에 복사할 길이를 3보다 큰 값으로 입력한다면 copy에 할당된 값인 6을 초과하므로 에러가 뜬다.

그렇다면 이것을 더 길게 복사하고 싶다면 copy에 할당된 값을 늘려주면 에러 없이 정상 출력된다. 

 

   ② Arrays.copyOf

String[] str = {"사과", "바나나", "딸기", "수박", "참외"};

// 복사 배열 = Arrays.copyOf(원본 배열, 새로운 배열 크기);
String[] copy = Arrays.copyOf(str, 7);

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

▼실행결과

사과 바나나 딸기 수박 참외 null null

복사 배열인 copy는 원본 배열인 str을 복사하는데, copy 배열 크기를 새롭게 7로 할당하여 str값을 갖고 오겠다는 뜻이다. 그러면 위의 실행결과가 나오는데 여기서 null은 0의 기본값이다. 정수형으로 출력하면 빈 공간에 0으로 나오지만 지금은 문자열로 출력하였기 때문에 null값이 출력된 것이다.

 

String[] str = {"사과", "바나나", "딸기", "수박", "참외"};

String[] copy = Arrays.copyOf(str, 3);

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

▼실행결과

사과 바나나 딸기

복사 배열 copy의 배열 크기를 3으로 지정하였다. 그러면 원본 배열 str에 들어있는 인덱스값이 순서대로 copy의 배열 크기 만큼만 출력이 된다.

 

     cf) Arrays.copyOfRange()

String[] str = {"사과", "바나나", "딸기", "수박", "참외"};

// Arrays.copyOfRange(복사할배열, 시작인덱스, 끝인덱스);
String[] copy = Arrays.copyOfRagne(str, 1, 3);

System.out.print(Arrays.copyOfRange());

 

   ③ clone

String[] str = {"사과", "딸기", "바나나", "수박", "복숭아", "멜론"};

// 복사 배열 = 원본 배열.clone();
String[] copy = str.clone();

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

▼실행결과

사과 딸기 바나나 수박 복숭아 멜론

clone은 말 그대로 원본을 온전히 복사하고 싶을 때 사용하면 된다. System.arraycopy나 Array.cpoyOf처럼 별도로 범위를 지정할 수 없기 때문이다.

 

   ④ 비교

     - System.arraycopy : 몇 번째 인덱스부터 몇 번째 인덱스까지 출력할 건지 설정이 가능하다.

     - Array.copyOf: 인덱스 설정이 불가하고, 원본 배열의 0번째 인덱스부터 출력된다.

                         입력한 값만큼 복사가 되며, 그 값이 곧 배열의 크기로 지정된다.

     - clone: 인덱스와 배열의 크기, 복사할 길이를 지정할 수 없다. 즉, 원본 배열이 그대로 복사된다.

반응형