본문 바로가기

JAVA/JAVA

자바의 정석 [5-1] 배열

배열(array)이란?

배열은 같은 타입의 여러 변수를 하나의 묶음으로 다루는 것

int[] score = new int[5]; // 5개의 int 값을 저장할 수 있는 배열을 생성

- 변수 score는 배열을 다루는데 필요한 참조변수일 뿐 값을 저장하기 위한 공간은 아님

- 배열은 각 저장공간이 연속적으로 배치되어 있음

 

배열의 선언과 생성

선언방법 선언 예
타입[] 변수이름;

int[] score;

String[] name;

타입 변수이름[];

int score[];

String name[];

 

- 배열을 선언하는 것은 단지 생성된 배열을 다루기 위한 참조변수를 위한 공간이 만들어질 뿐이고, 배열을 생성해야만 비로소 값을 저장할 수 있는 공간이 만들어지는 것

- 배열을 생성하기 위해서는 연산자 'new'와 함께 배열의 타입과 길이를 지정해 주어야 함

타입[] 변수이름;                    // 배열을 선언(배열을 다루기 위한 참조변수 선언)
변수이름 = new 타입[길이];     // 배열을 생성(실제 저장공간을 생성)

- 배열요소는 자동적으로 기본값(default) 값으로 초기화됨

 ex) int[] arr = new int[5];   // 0으로 초기화

 

배열의 길이와 인덱스

- 생성된 배열의 각 저장공간을 '배열의 요소(element)'라고 하며, '배열이름[인덱스]'의 형식으로 배열의 요소에 접근

- 인덱스(index)는 배열의 요소마다 붙여진 일련번호로 각 요소를 구별하는데 사용됨

인덱스(index)의 범위는 0부터 '배열길이-1'까지

※ 배열을 다룰 때 index의 범위를 벗어난 값을 index로 사용하지 않아야 함!

 >> 유효하지 않은 값을 index로 사용하면, 실행 시 ArrayIndexOutOfBoundsException이 발생함

배열의 길이는 int범위의 양의 정수(0도 포함)이어야 한다.

 

- 자바에서는 JVM이 모든 배열의 길이를 별도로 관리하며, '배열이름.length'를 통해서 배열의 길이에 대한 정보를 얻을 수 있음

int[] arr = new int[5];

for(int i = 0; i < arr.length(); i++)
	System.out.println(arr[i]);

 

- 배열은 한번 선언되고 나면 길이를 변경할 수 없기 때문에 배열의 길이를 변경하기 위해서는 기존 배열의 길이보다 더 큰 길이의 배열을 새로 생성한 다음, 기존의 배열에 저장된 값들을 새로운 배열에 복사하여야 함

 

배열의 초기화

- 배열은 생성과 동시에 자동적으로 자신의 타입에 해당하는 기본값으로 초기화되므로 배열을 사용하기 전에 따로 초기화를 해주지 않아도 되지만, 원하는 값을 저장하려면 각 요소마다 값을 지정해줘야 함

int arr[] = new int[5];

for(int i = 0; i < arr.length(); i++)
	arr[i] = i*10+50;

아래와 같이 사용하면 더 간단하게 가능

int[] arr2 = new int[]{50, 60, 70, 80, 90};	// 배열의 생성과 초기화를 동시에
int[] arr2 = {50, 60, 70, 80, 90};			// 이렇게도 가능함

int[] arr3;
arr3 = new int[]{50, 60, 70, 80, 90};		// 가능
arr3 = {50, 60, 70, 80, 90};				// 불가능!!!!

괄호{} 안에 아무 것도 넣지 않으면, 길이가 0인 배열이 생성됨

int[] arr = new int[0];
int[] arr = new int[]{};
int[] arr = {};

 

- 배열을 출력할 때는 Arrays.toString(배열이름) 메서드를 사용하면 [첫번째 요소, 두번째 요소, ...] 와 같은 형식의 문자열로 만들어서 반환됨

int[] arr = {10, 20, 30, 40, 50};
System.out.println(Arrays.toString(arr));

// 출력 : [10, 20, 30, 40, 50]

// ※ ※ ※ ※ ※ ※ ※ ※ 
System.out.println(arr);
// 출력 : 타입@주소 ex)I@14318bb 와 같이 나옴!
// I는 1차원 int배열
// 143188bb는 배열의 주소

- BUT!!! char 배열은 println메서드로 출력하면 각 요소가 구분자없이 그대로 출력됨!

char[] chArr = {'a','b','c','d'};
System.out.println(chArr);	// abcd가 출력됨

 

배열의 복사

- 배열을 복사하는 방법은 1) for문을 이용해서 배열을 복사하는 방법 2) System.arraycopy() 이용하는 방법 두가지가 있음

1) for문을 이용해서 배열을 복사하는 방법

int[] arr = new int[5];
	. . .
int tmp = new int[arr.length*2];	// 기존 배열보다 길이가 2배인 배열 생성

for(int i = 0; i < arr.length; i++)
	tmp[i] = arr[i];	// arr[i]의 값을 tmp[i]에 저장

arr = tmp;	// 참조변수 arr이 새로운 배열을 가리키게 함

- 배열은 참조변수를 통해서만 접근할 수 있기 때문에, 자신을 가리키는 참조변수가 없는 배열은 사용할 수 없음. 이렇게 쓸모없게 된 배열은 JVM의 가비지 컬렉터에 의해서 자동적으로 메모리에서 제거됨

2) System.arraycopy() 이용하는 방법

- 이 함수를 사용하면 지정된 범위의 값들을 한 번에 통째로 복사함

- 배열의 복사는 for문보다 System.arraycopy()를 사용하는 것이 효율적!

for(int i = 0; i < arr.length; i++)
	>> System.arraycopy(arr, 0, newNum, 0, arr.length);
    // arr[0]에서 newNum[0]으로 arr.length개의 데이터를 복사

- 이때 복사하려는 배열의 위치가 적절하지 못하여 복사하련느 내용보다 여유 공간이 적으면 에러(ArrayIndexOutOfBoundsException)가 발생

 

 

출처 : <자바의 정석>, 남궁 성