Updated:

배열

 같은 타입의 변수를 반복해서 선언하고 반복해서 사용하는 문재를 해경하는 것이 배열이다.

배열의 선언과 생성

 배열은 같은 타입의 변수를 사용하기 편하게 하나로 묶어둔 것이다.

int[] students;  // 배열 변수 선언
students = new int[5] // 배열 생성

 자바는 배열을 생성할 때 그 내부값을 자동으로 초기화한다. 숫자는 0, boolean은 false, String은 null로 초기화 된다.

배열 참조값 보관

 new int[5]로 배열을 생성하면 배열의 크기만큼 메모리를 확보한다(int 형을 5개 사용하면 4byte * 5 = 20byte를 확보한다).
 배열을 생성하고 나면 자바는 메모리 어딘가에 있는 이 배열에 접근할 수 있는 참조값(주소)(e.g, x001)을 반환한다. 여기서 x001이라고 표현한 것이 참조값이다. 예를 들어, int[] students에 생성된 배열의 참조값을 보관한다. int[] students 변수는 new int[5]로 생성한 배열의 참조값을 가지고 있다. 이 참조값을 통해 배열을 참조할 수 있다.

int[] students = new int[5];  // 배열 생성
int[] students = x001;  // new int[5]의 결과로 x001 참조값 반환
students = x001;  // 최종 결과

System.out.println(students); // I@4617c264 출력, I는 int형 배열, @뒤는 16진수 참조값

인덱스

 배열은 변수와 사용법이 비슷한데, 차이점이 있다면 []사이에 숫자 번호를 넣어주면 된다. 배열의 위치를 나타내는 숫자를 인덱스(index)라 한다. 만약 접근 가능한 배열의 인덱스 범위를 넘어가면 오류가 발생한다.
 배열에 값을 대입하든 배열의 값을 사용하든 간에 일반적인 변수의 사용법은 같다.

기본형 vs 참조형

 자바의 변수 데이터 타입을 가장 크게 보면 기본형과 참조형으로 분류할 수 있다. 사용하는 값을 직접 넣을 수 있는 기본형, 그리고 메모리의 참조값을 넣을 수 있는 참조형으로 분류할 수 있다.

  • 기본형(Primitive Type): int, long, boolean처럼 변수에 사용할 값을 직접 넣을 수 있는 데이터 타입을 기본형(Primitive Type)이라 한다.
  • 참조형(Reference Type): int[] students와 같이 데이터에 접근하기 위한 참조(주소)를 저장하는 데이터 타입을 참조형(Reference Type)이라 한다.

 기본형은 선언과 동시에 크기가 정해진다. 따라서 크기를 동적으로 바꾸거나 할 수는 없다. 반면에 참조형은 크기를 동적으로 할당할 수 있다. 이런 것을 동적 메모리 할당이라 한다. 기본형은 선언과 동시에 사이즈가 정적으로 정해지지만, 참조형을 사용하면 이처럼 동적으로 크기가 변해서 유연성을 제공할 수 있다. 기본형은 사용할 값을 직접 저장한다. 반면에 참조형은 메모리에 저장된 배열이나 객체의 참조를 저장한다. 이로 인해 참조형을 더 복잡한 데이터 구조를 만들고 관리할 수 있다. 반면 기본형은 더 빠르고 메모리를 효율적으로 처리한다.

배열 리펙토링

 리펙토링(Refactoring)은 기존의 코드 기능은 유지하면서 내부 구조를 개성하여 가독성을 높이고, 유지보수를 용이하게 하는 과정을 뜻한다. 이는 중복을 제거하고, 복잡성을 줄이며, 이해하기 쉬운 코드로 만들기 위해 수행된다. 리팩토링은 버그를 줄이고, 프로그램의 성능을 향상시킬 수도 있으며, 코드의 설계를 개선하는 데에도 도움이 된다. 즉, 작동하는 기능은 똑같은데, 코드를 개선하는 것을 리펙토링이라한다.

package array;

public class Array1Ref2 {

    public static void main(String[] args) {
        int[] students;
        students = new int[5];

        // 변수 값 대입
        students[0] = 90;
        students[1] = 80;
        students[2] = 70;
        students[3] = 60;
        students[4] = 50;

        // 변수 값 사용
        for(int i = 0; i < students.length; i++){
            System.out.println("학생" + (i + 1) + "점수: " + students[i]);
        }
    }
}

 반복문을 사용해서 배열을 통해 값을 사용하는 부분을 효과적으로 변경했다.
 배열은 {}을 사용해서 생성과 동시에 편리하게 초기화 하는 기능을 제공한다.

int[] students1;
students1 = new int[]{90, 80, 70, 60, 50};  // 배열 생성과 초기화

int[] students2 = new int[]{90, 80, 70, 60, 50}; // 한줄도 가능

 배열은 {}만 사용해서 생성과 동시에 편리하게 초기화 하는 기능을 제공한다.

int[] students = {90, 80, 70, 60, 50};

// 오류
int students;
students = {90, 80, 70, 60, 50};

 이때는 배열 변수의 선언을 한 줄에 함께 사용할 때만 가능하다.

2차원 배열

 2차원 배열은 행과 열로 구성된다.

 2차원 배열은 int[][] arr = new int[2][3]와 같이 선언하고 생성한다. 그리고 arr[1][2]와 같이 사용하는데, 먼저 행 번호를 찾고, 그 다음에 열 번호를 찾으면 된다.
arr[행][열], arr[row][column]

2차원 배열 리펙토링

 다음과 같이 코드를 작성할 수 있다.

package array;

public class ArrayDi2 {

    public static void main(String[] args) {
        // 2x3 2차원 배열을 만든다
        int[][] arr = new int[2][3];    // 행(row), 열(column)

        arr[0][0] = 1;  // 0행, 0열
        arr[0][1] = 2;  // 0행, 1열
        arr[0][2] = 3;  // 0행, 2열
        arr[1][0] = 4;  // 1행, 0열
        arr[1][1] = 5;  // 1행, 1열
        arr[1][2] = 6;  // 1행, 2열

        for(int row = 0; row < 2; row++){
            for(int column = 0; column < 3; column++){
                System.out.print(arr[row][column] + " ");
            }
            System.out.println();
        }
    }
}

 위 코드는 2가지 개선할 부분이 있다.

  • 초기화: 기존 배열처럼 2차원 배열도 편리하게 초기화 할 수 있다.
  • for문에서 배열의 길이 활용
package array;

public class ArrayDi3 {

    public static void main(String[] args) {
        // 2x3 2차원 배열, 초기화
        int[][] arr = {
                {1, 2, 3},
                {4, 5, 6}
        };
        
        // 2차원 배열의 길이를 활용
        for(int row = 0; row < arr.length; row++){
            for(int column = 0; column < arr[row].length; column++){
                System.out.print(arr[row][column] + " ");
            }
            System.out.println();
        }
    }
}

 for문에서 2차원 배열의 길이를 활용했다.

  • arr.length는 행의 길이를 뜻한다.
  • arr[row].length는 열의 길이를 뜻한다.

향상된 for문

 향상된 for문(Enhanced For Loop)을 이해하려면 배열을 먼저 알아야 한다. 각각의 요소를 탐색한다는 의미로 for-each문이라고도 부른다. 향상된 for문은 배열을 사용할 때 기존 for문 보다 더 편리하게 사용할 수 있다.

for (변수: 배열 또는 컬렉션) {
  // 배열 또는 컬렉션의 요소를 순회하면서 수행할 작업
}

 다음 코드를 보자.

package array;

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

        //일반 for문
        for (int i = 0; i < numbers.length; ++i) {
            int number = numbers[i];
            System.out.println(number);
        }

        // 향상된 for문, for-each문, 단축키: iter
        for (int number : numbers) {
            System.out.println(number);
        }

        // for-each문을 사용할 수 없는 경우, 증가하는 index 값 필요
        for (int i = 0; i < numbers.length; ++i) {
            System.out.println("number" + i + "번의 결과는: " + numbers[i]);
        }
    }
}

 향상된 for문은 일반 for문과 동일하게 작동한다. 향상된 for문은 배열의 인덱스를 사용하지 않고, 종료 조건을 주지 않아도 된다. 단순히 해당 배열을 처음부터 끝까지 탐색한다. 향상된 for문은 배열의 인덱스를 사용하지 않고도 배열의 요소를 순회할 수 있기 때문에 코드가 간결하고 가독성이 좋다.
 그러나 향상된 for문을 사용하지 못하는 경우가 있다. 향상된 for문에는 증가하는 인덱스 값이 감추어져 있다. 따라서 “int i”와 같은 증가하는 인덱스 값을 직접 사용해야 하는 경우에는 향상된 for문을 사용할 수 없다.

댓글남기기