언어(Language)/Java

[Java] 자바 배열(Array) 개념 정리 및 사용법

잇트루 2022. 9. 13. 02:00
반응형

어떤 값을 저장하기 위해서는 변수를 사용한다. 하지만, 변수는 하나의 값만 저장할 수 있는 단점이 있다.

예를 들어, 날짜 데이터, 학급별 학생 수, 회원들의 아이디 등 데이터들을 변수로 표현하려면, 선언해야 하는 변수는 무수히 많아진다. 이는 결국 사용자가 비슷한 데이터들을 다른 이름의 변수로 공장에서 찍어 내듯이 선언해야 할 것이다.

 

배열이란? (Array)

배열은 변수의 단점을 해결할 수 있는 수단으로, 동일한 타입의 값들을 하나의 묶음으로 저장한 자료 구조이다. 즉, 여러 값들이 같은 의미를 지니면서 서로 연관성이 있을 때, 이들을 하나의 덩어리로 묶을 수 있다. 이렇게 묶인 데이터들의 집합을 배열이라 한다.

 

배열의 차원 (Dimension)

배열을 사용할 때, 1차원 배열부터 2차원 배열, …, n차원 배열까지 다양한 차원의 배열을 생성할 수 있다. 필요에 따라서는 3차원 배열 또는 4차원 배열까지도 만들어 사용할 수 있지만, 대부분 1차원 배열과 2차원 배열 정도로 사용한다.

여기서 말하는 차원은 배열이 중첩된 정도를 의미한다. 즉, 배열의 요소가 또 다른 배열을 구성하는 것이다.

 

1차원 배열

배열이 중첩이 없는 경우이다. 즉, 배열의 요소가 배열이 아닌 경우를 뜻한다.

예) {1, 2, 3, 4, 5}, {1, 3, 5, 7, 9}, {가, 나, 다, 라}, {a, b, c, d, e}, … 등

 

2차원 배열

배열이 한 번 중첩된 경우이다. 즉, 배열의 요소가 배열인 경우를 뜻한다.

예) {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}, {{a, b, c, d}, {e, f, g, h}}, … 등

 

1차원 배열

1차원 배열은 배열의 요소가 값인 배열을 의미한다. 자바에서는 1차원 배열을 선언할 때, 다음과 같이 데이터 타입 뒤에 대괄호 []를 붙인 뒤, 배열의 이름을 입력하여 선언하고 초기화할 수 있다.

int[] studentNumber;
studetNumber = new int[30];

 

또한, 배열은 선언과 초기화를 동시에 할 수도 있다.

int[] studentNumber = new int[30];

int[] studentNumber;

배열을 가리킬 참조 변수 studentNumber를 선언한다.

studentNumber에는 생성할 배열의 주소 값을 가진다.

 

studentNumber = new int[30];

총 30개의 int형 데이터를 저장할 수 있는 배열이 생성된다.

studentNumber의 주소 값 위치부터 연속적으로 저장할 수 있는 메모리 공간을 차지한다.

생성 한 배열은 기본값 0으로 초기화된다.

 

배열에 저장할 값을 담으면서 초기화할 수도 있다.

int[] studentNumber = new int[30] {1, 2, 3, ..., 30};

int[] studentNumber = new int[] {1, 2, 3, ..., 30}; // 자동으로 new int[30] 크기로 초기화

int[] studentNumber = {1, 2, 3, ..., 30}; // new int[]를 생략하고 초기화 가능

 

studentNumber가 참조 변수인 이유

자바에서의 배열은 참조 타입에 해당한다. 따라서 int[] 형태의 문법으로 배열을 선언한 studentNumber는 이후에 생성될 배열의 주소 값을 담은 참조 변수가 된다.

 

일반 변수를 선언할 때에는, 저장할 메모리 공간을 확보하고, 해당 메모리 공간에 값을 저장한다. 이러한 변수 선언 방식은 컴퓨터가 변수를 선언할 때, 얼마만큼 메모리 공간을 확보해야 하는지 알 수 있다.

하지만, 배열의 경우 배열을 선언하는 시점에 배열이 몇 개의 요소를 가질지 알 수 없기 때문에 배열의 시작 주소 값을 담을 메모리 공간만이 확보된다. 이후 배열이 생성되고 난 뒤, 해당 배열의 시작 주소 값이 참조 변수에 할당되는 구조이다.

 

아래의 코드를 살펴보면, 더욱 쉽게 이해할 수 있을 것이다.

// 변수
int num; // int형인 8byte 메모리를 확보함

// 배열
int[] nums; // 배열의 요소가 몇 개인지 모름. 생성될 배열의 시작 주소 값을 담음

 

배열의 값에 접근하기

배열에 저장된 요소(값)에 접근하려면, 배열의 참조 변수 이름과 배열의 인덱스를 활용해야 한다.

int[] studentNumber = {1, 2, 3, ..., 30};

System.out.println(studentNumber[0]); // 1
System.out.println(studentNumber[1]); // 2
System.out.println(studentNumber[2]); // 3
...
System.out.println(studentNumber[29]); // 30

인덱스의 경우, 0부터 시작한다. 따라서 studentNumber 배열의 첫 번째 요소 1의 인덱스는 0이 된다.

즉, 배열의 인덱스는 0, 1, 2, …, studentNumber의 길이 - 1까지 이다.

 

배열의 길이

배열의 길이는 배열이 가진 요소의 개수를 뜻한다. 즉, studentNumber의 길이는 30이 된다. 배열의 길이를 구하는 방법은 배열이름.length이다.

int[] studentNumber = new int[30];

System.out.println(studentNumber.length); // 30

배열의 길이는 자바를 사용하면서 인덱스를 다룰 때 자주 사용될 것이다.

배열의 길이가 30이면, 배열의 마지막 요소의 인덱스는 29이다. 즉, 배열의 길이 - 1이다.

 

2차원 배열

2차원 배열은 배열의 각 요소가 또 다른 배열을 가진 구조이다.

2차원 배열의 선언과 초기화하는 방법은 1차원 배열과 유사하다.

int[][] classStudentNumber;
classStudentNumber = new int[10][30];

 

2차원 배열 또한 한 줄로 선언과 초기화를 동시에 할 수 있다.

int[][] classStudentNumber = new int[10][30];

 

classStudentNumber의 경우 다음과 같은 형태의 2차원 배열이 만들어진다.

{{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0},
{0, 0, ..., 0}}

즉, 10개의 행과 30개의 열을 가진 2차원 행렬과 유사한 형태로 생성된다.

 

가변 배열

2차원 이상의 다차원 배열에서는 마지막 차수에 해당하는 배열의 길이를 고정하지 않아도 된다. 이를 가변 배열이라고 한다.

가변 배열은 다음과 같은 형태로 선언하여 초기화를 할 수 있다.

int[][] member = new int[5][];

이는 외부 배열의 크기를 5로 지정하였으나, 내부에 존재하는 배열은 지정하지 않은 배열이다. 이러한 가변 배열은 내부에 존재하는 배열의 크기를 자유롭게 지정할 수 있다.

 

가변 배열의 내부 요소에 배열을 지정하지 않고 초기화하였을 경우 내부 요소의 값은 null로 초기화된다. 즉, 가변 배열을 선언하고 초기화하여 출력하면 다음과 같이 나타난다.

int[][] member = new int[5][];

System.out.println(Arrays.toString(member));
// [null, null, null, null, null]

 

내부 배열을 생성하는 방법

int[][] member = new int[5][];

member[0] = new int[2];
member[1] = new int[3];
member[2] = new int[4];
member[3] = new int[3];
member[4] = new int[2];

System.out.println(Arrays.toString(member[0])); // [0, 0]
System.out.println(Arrays.toString(member[1])); // [0, 0, 0]
System.out.println(Arrays.toString(member[2])); // [0, 0, 0, 0]
System.out.println(Arrays.toString(member[3])); // [0, 0, 0]
System.out.println(Arrays.toString(member[4])); // [0, 0]

 

가변 배열도 선언과 동시에 초기화할 수 있다.

int[][] member = {
                {1, 2},
                {3, 4, 5},
                {6, 7, 8, 9},
                {10, 11, 12},
                {13, 14}
        };

System.out.println(Arrays.toString(member[0])); // [1, 2]
System.out.println(Arrays.toString(member[1])); // [3, 4, 5]
System.out.println(Arrays.toString(member[2])); // [6, 7, 8, 9]
System.out.println(Arrays.toString(member[3])); // [10, 11, 12]
System.out.println(Arrays.toString(member[4])); // [13, 14]

 

배열 탐색

배열은 반복문을 활용하여 탐색할 수 있다. 일반적으로 인덱스와 배열의 길이를 활용하여 탐색하는 방법이 가장 많이 사용된다.

 

for문을 활용한 탐색

다음은 배열의 모든 요소를 더하는 예제이다.

int[] arr = {1, 2, 3, 4, 5};
int sum = 0;

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

System.out.println(sum);

 

while문을 활용한 탐색

int[] arr = {1, 2, 3, 4, 5};
int sum = 0;
int i = 0;

while (i < arr.length) {
	sum += arr[i];
	i += 1;
}

System.out.println(sum);

 

향상된 for문 (Enhanced for)을 활용한 탐색

int[] arr = {1, 2, 3, 4, 5};
int sum = 0;

for (int i: arr) {
    sum += i;
}

System.out.println(sum);

향상된 for문 사용 시 주의할 점

향상된 for문은 배열의 값을 읽어오는 것만 가능하다.

따라서 향상된 for문으로 배열을 실행 블록에서 배열의 값을 수정할 수는 없다.

반응형