CodeGym /행동 /JAVA 25 SELF /배열 소개

배열 소개

JAVA 25 SELF
레벨 7 , 레슨 1
사용 가능

1. 배열은 요소의 컨테이너

대부분의 사람들은 컴퓨터가 방대한 양의 정보를 처리할 수 있다는 얘기를 들어 봤을 것입니다. 조건문(if-else)과 반복문(for, while)이 물론 큰 도움이 됩니다. 하지만 처리할 데이터를 어딘가에 저장해야 하므로 그것만으로는 충분하지 않습니다.

이럴 때 Java에는, 그리고 거의 모든 프로그래밍 언어에는, 배열(Array)이라는 훌륭한 도구가 있습니다. 테이블이라고 부르기도 합니다.

배열은 하나의 값이 아니라 여러 개의 값을 담을 수 있는 특별한 객체입니다.

Java의 배열(Array)

변수를 어떤 값을 담는 상자에 비유해 봤다면, 배열은 내부가 구획으로 나뉘어 있는 상자에 더 가깝습니다. “박스-배열”의 각 구획(칸)에는 번호가 있습니다. 번호는 당연히 0부터 시작합니다…

다른 비유도 해 봅시다. 단독주택과 아파트를 비교해 보세요. 단독주택에는 한 가족이 살지만, 아파트는 여러 세대로 나뉘어 있습니다. 단독주택에 사는 가족에게 편지를 보내려면 그 집의 고유 주소만 적으면 됩니다. 하지만 아파트에 사는 가족에게 보내려면 집의 고유 주소 그리고 호수까지 적어야 하죠.

배열 변수는 아파트 같은 변수입니다. 하나가 아니라 여러 값을 담을 수 있습니다. 그런 변수 안에는 여러 “세대(칸)”가 있고, 각 칸은 자신의 번호(인덱스)로 접근할 수 있습니다.

이를 위해 변수 이름 뒤의 대괄호에 접근할 칸의 인덱스를 지정합니다. 아주 간단합니다:


array[indeks] = znachenie;
인덱스로 배열의 칸(요소)에 값을 대입하기

여기서 array는 배열 변수의 이름, indeks는 배열에서의 칸 번호(인덱스), znachenie는 해당 칸에 저장하려는 값입니다.

이제 배열을 어떻게 만드는지부터 알아봅시다.

2. Java에서 배열 생성

Java에서 배열 생성

당신의 프로그램이 어딘가에 100개의 정수를 저장해야 한다고 해 봅시다. 배열이 딱 맞겠죠. 그럼 어떻게 만들까요?

정수 하나만 저장한다면 int 타입으로 충분합니다. 그런데 100개의 정수를 저장하려면 int 타입의 배열이 필요하겠죠. 생성 코드는 다음과 같습니다:

int[] array = new int[100];
int 정수 100개짜리 배열 생성

무엇이 쓰였는지 살펴봅시다.

등호 왼쪽에는 array라는 이름과 int[] 타입의 변수 선언이 있습니다. int 타입 뒤의 대괄호는 이 “상자”에는 하나가 아니라 여러 값을 저장할 수 있음을 암시합니다.

등호 오른쪽에는 new라는 “객체 생성”이 있고, int 타입의 요소를 100개(칸) 만들겠다는 뜻입니다. 어렵지 않죠.

예를 들어 20칸짜리 실수 저장용 배열을 만들고 싶다면 코드는 대략 다음과 같습니다:

double[] vals = new double[20];
실수 20개짜리 배열 생성

배열의 칸 수를 배열의 크기 또는 배열의 길이라고 부릅니다. 여러 값을 저장할 수 있다는 특성 때문에 배열을 컨테이너라고도 합니다.

중요: 배열 컨테이너의 크기는 한번 만들면 변경할 수 없습니다.

새로운 배열을 생성할 수는 있지만, 이미 만들어진 컨테이너의 길이는 바꿀 수 없습니다.

3. 배열 요소 다루기

배열 요소 다루기

배열을 만드는 법을 배웠으니, 이제는 올바르게 다루는 법을 살펴봅시다.

일반 변수와 거의 같습니다. 다만 배열 변수의 이름 뒤에 우리가 다루려는 칸의 번호를 반드시 지정해야 합니다.

배열 칸의 번호(인덱스)는 항상 0부터 시작합니다. 요소가 10개인 배열의 인덱스는 0..9, 요소가 200개라면 0..199입니다. 그 이후도 같은 규칙이 적용됩니다.

예제:

int[] a = new int[10];	// int 타입 요소 10개짜리 배열 생성

a[2] = 4;				// 인덱스 2 칸에 값 4를 저장

a[7] = 9;				// 인덱스 7 칸에 값 9를 저장

a[9] = a[2] + a[5];		// 인덱스 9 칸에, 칸 2에 들어 있는 값과 	
                        // (4가 들어 있음) 칸 5에 들어 있는 값(0이 들어 있음)의 합을 저장 

이 코드를 실행하면 메모리에 다음과 같이 저장됩니다:

int 배열 요소 작업

배열 왼쪽의 회색 열은 칸의 번호(인덱스)입니다. 칸에는 우리가 넣은 값 4, 9, 4가 들어 있습니다. 배열을 만들자마자 칸에는 기본값인 0이 채워져 있습니다.

중요. 배열의 모든 칸은 동일한 데이터 타입을 갖습니다. 문자열 String 배열을 만들었다면, 그 칸에는 문자열만 저장할 수 있습니다. 배열의 데이터 타입은 생성할 때 정해집니다. 이후에는 데이터 타입도, 길이도 바꿀 수 없습니다.

4. 메모리에서의 배열

앞선 그림들은 약간 단순화되어 있습니다.

배열(문자열과 마찬가지)을 만들 때 메모리에는 두 블록이 할당됩니다. 하나는 배열(컨테이너) 자체를 저장하는 용도이고, 다른 하나는 그 배열의 주소를 저장하는 변수용입니다. 더 정확한 상황은 아래 그림과 같습니다:

메모리에서의 배열

초록색은 10개의 int 요소를 가진 배열과, 그 배열의 주소(참조)를 저장하는 int[] 타입 변수를 나타냅니다.

비교를 위해 파란색은 값 199를 저장하는 일반적인 int 타입 변수를 나타냅니다.

문자열이 메모리에 저장되는 방식이 떠오르지 않나요?

맞습니다. 문자열과 마찬가지로 “배열 타입의 변수”는 서로 대입할 수 있습니다:

int[] a = new int[10];		// int 타입 요소 10개짜리 배열 생성

a[2] = 4;					// 인덱스 2 칸에 값 4 저장
a[7] = 9;					// 인덱스 7 칸에 값 9 저장

int[] b = a;				// 변수 b에 변수 a가 가진 주소를 복사해 저장
                            // 이제 a와 b는 메모리의 같은 배열 객체를 가리킴

a[9] = b[2] + a[7];			// 배열 객체의 인덱스 9 칸에,
                            // 칸 2(4가 저장됨)와 칸 7(9가 저장됨)의 합을 저장 

이때 배열 객체 자체는 그대로 있고, ab 변수는 같은 객체를 가리키는 동일한 주소(참조)를 저장합니다. 그림을 보세요:

메모리에서의 배열 2

5. 배열 더 자세히 다루기

배열은 어떤 타입으로든 만들 수 있습니다. 타입 이름 뒤에 대괄호만 붙이면 됩니다. 배열 생성의 일반형은 다음과 같습니다:

tip[] imya = new tip[kolichestvo];
배열 생성의 정형화된 형태

여기서 tip은 배열에 저장할 요소(칸)의 타입이고, imya는 배열에 접근할 때 사용할 변수 이름이며, kolichestvo는 배열의 칸 수입니다.

위 예시는 배열 변수 선언과 배열 객체 생성을 함께 보여 주는 정형화된 형태입니다. 사실 이 둘은 서로 독립적입니다. 배열 변수와 배열 객체를 따로 만들 수도 있습니다:

tip[] imya;
imya = new tip[kolichestvo];
변수와 배열을 따로 생성

또 하나 중요한 점

배열의 인덱스나 배열의 요소 개수는 변수나 심지어 식(표현식)이 될 수도 있습니다.

예제:

int n = 100;
int[] a = new int[n];			// 	n개의 요소로 배열 생성

int n = 100;
int[] a = new int[n * 2 + 3];	// 	요소 203개짜리 배열 생성

int n = 100;
int[] a = new int[n];
a[n-1] = 2;					// a[99] = 2;
a[n-2] = 3;					// a[98] = 3;
a[n/5] = a[n-1] + a[n-2]	// a[20] = a[99] + a[98];

배열 범위를 벗어남

참고로, 배열에 존재하지 않는 인덱스(이 예에서는 0..99를 제외한 모든 정수)로 접근을 시도하면, 프로그램은 ArrayIndexOutOfBoundsException — 배열의 경계를 벗어남 오류와 함께 비정상 종료됩니다.

6. 배열의 길이

앞선 예제에서 보았듯이, 배열 타입의 변수를 먼저 만들고 나중에 코드 어딘가에서 그 변수에 값(배열 객체의 참조)을 대입할 수 있습니다. 심지어 다음과 같이도 할 수 있습니다:

int[] array;			//	int[] 타입의 배열 변수를 생성
if (a < 10)				// 변수 a가 10보다 작으면
   array = new int[10];	// 요소 10개짜리 배열을 생성
else					// 그렇지 않으면
   array = new int[20];	// 요소 20개짜리 배열을 생성 

그렇다면 이런 배열을 이후에는 어떻게 다룰까요? 요소가 몇 개인지 어떻게 알 수 있을까요?

배열에는 length라는 전용 속성(변수)이 있습니다. 배열의 길이는 다음 식으로 알 수 있습니다:

array.length;
length 속성으로 배열 길이 얻기

여기서 array는 배열 변수의 이름이고, length는 배열 객체의 속성 이름입니다. length 속성의 값은 바꿀 수 없습니다. 이 속성 값을 다른 변수에 대입하는 것은 가능하지만, length 자체에 값을 대입할 수는 없습니다(컴파일 오류가 발생합니다).

이전 예제를 다음과 같이 이어갈 수 있습니다:

int[] array;			//	int[] 타입의 배열 변수를 생성
if (a < 10)				// 변수 a가 10보다 작으면
   array = new int[10];	// 요소 10개짜리 배열을 생성
else					// 그렇지 않으면
   array = new int[20];	// 요소 20개짜리 배열을 생성 

for (int i = 0; i < array.length; i++)	// 배열의 모든 요소를 순회: 0부터 array.length - 1까지
{
   System.out.println(array[i]);
}

7. Java 배열에 대한 사실들

배열에 대해 알게 된 사실들을 정리해 봅시다:

  • 사실 1. 배열은 여러 개의 칸(요소)으로 이루어져 있습니다.
  • 사실 2. 특정 칸에 접근하려면 그 칸의 번호(인덱스)를 지정해야 합니다.
  • 사실 3. 모든 칸의 타입은 동일합니다.
  • 사실 4. 모든 칸의 초기값은 0이며, 주소(참조)를 저장하는 칸은 null, false(boolean 타입의 경우)입니다.
  • 사실 5. String[] list는 단지 변수 선언일 뿐입니다. 컨테이너(배열 객체)는 아직 생성되지 않았습니다. 사용하려면 배열(컨테이너)을 생성해서 이 변수에 넣은 뒤 사용해야 합니다. 아래 예제를 보세요.
  • 사실 6. 배열 객체(컨테이너)를 생성할 때는 길이—칸의 개수—를 지정해야 합니다. 형식은 다음과 같습니다: new TypeName[n];
  • 사실 7. 배열의 길이는 .length 속성으로 알 수 있습니다.
  • 사실 8. 배열을 만든 뒤에는 요소 타입도, 요소 개수도 바꿀 수 없습니다.
String s;				// s는 null
String[] list;			// list는 null

list = new String[10];	// 변수 list는 10개의 문자열을 담는 배열 객체의 참조(주소)를 저장함
int n = list.length;	// n은 10

list = new String[0];	// 이제 list에는 요소가 0개인 배열이 들어 있음 
                        // 배열 객체는 존재하지만, 요소를 저장할 수 없음

list = null;
System.out.println(list[1]); // 프로그램 오류가 발생하여 비정상 종료됨 
                            // list에는 비어 있는 참조 — null이 들어 있음

list = new String[10];
System.out.println(list[10]);	// 오류 발생 — 배열 범위를 벗어남
//	list에 요소/칸이 10개라면, 유효한 인덱스는 0 1 2 3 4 5 6 7 8 9 — 총 10개. 	
1
과제
JAVA 25 SELF, 레벨 7, 레슨 1
잠금
모험가의 배낭 준비 🎒
모험가의 배낭 준비 🎒
1
과제
JAVA 25 SELF, 레벨 7, 레슨 1
잠금
좋아하는 프로그래밍 언어 목록 평가 💬
좋아하는 프로그래밍 언어 목록 평가 💬
1
과제
JAVA 25 SELF, 레벨 7, 레슨 1
잠금
기상 관측소 센서 설정 ☀️
기상 관측소 센서 설정 ☀️
1
과제
JAVA 25 SELF, 레벨 7, 레슨 1
잠금
토너먼트 결과판 채우기 🏆
토너먼트 결과판 채우기 🏆
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION