변수는 1개의 데이터만 저장할 수 있습니다. 저장해야 할 데이터의 수가 많아지면 그만큼 많은 변수가 필요하고 코드도 매우 길어지겠죠? 하지만 배열을 사용하면 많은 양의 데이터를 적은 코드로 손쉽게 처리할 수 있습니다.
학생 30명의 성적을 저장하고, 평균값을 구한다고 가정해볼게요. 먼저 학생 30명의 성적을 저장하기 위해 변수 30개를 선언합니다.
int score1 = 83;
int score2 = 90;
int score3 = 87;
…
int score30= 75;
그리고 평균값을 구하기 위해 변수들을 모두 더합니다.
int sum = score1;
sum += score2;
sum += score3;
…
sum += score30;
위와 같은 방법은 매우 비효율적이고 지루한 코딩이 됩니다. 만약 전교 학생들의 성적을 처리할 경우 수백 개의 변수 선언으로 인해 코드는 끔찍해지겠죠! 많은 양의 데이터를 다루는 프로그램에서는 좀 더 효율적인 방법이 필요한데 이때 배열을 사용할 수 있습니다.
✅배열이란?
배열은 같은 타입의 데이터를 연속된 공간에 나열하고, 각 데이터에 인덱스(index)를 부여해놓은 자료구조입니다. 예를 들어 방금 위에서 언급했던 학생들의 성적은 다음과 같이 score 배열로 생성할 수 있습니다.
score 배열의 각 인덱스는 각 항목의 데이터를 읽거나 저장하는데 사용되며 다음과 같이 배열 이름 옆에 대괄호 [ ]에 기입됩니다. 인덱스는 0부터 시작합니다.
score[인덱스] |
예를 들어 score[0]은 83, score[1]은 90, score[2]는 87 값을 가진다고 할 때 이렇게 성적을 배열로 만들면 성적의 평균값은 배열의 인덱스를 이용해서 for문으로 쉽게 구할 수 있습니다.
int sum = 0;
for(int i=0; i<30; i++) {
sum += score[i];
}
int avg = sum / 30;
for문이 30번 반복 실행하면서 i가 0~29까지 변하고 있습니다. 따라서 sum 변수에는 score[0]~ score[29]까지 더해지고, 마지막으로 얻은 sum을 30으로 나누어 평균 avg를 얻습니다. 학생 수가 30명이 아니라 수백 명이 되어도 for문의 조건식 i<30만 변경하면 되므로 많은 양의 데이터를 적은 코드로 손쉽게 처리할 수 있습니다.
✔️배열의 특징
① 배열은 같은 타입의 데이터만 저장할 수 있습니다.
int 배열은 int 값만 저장 가능하고, String 배열은 문자열만 저장합니다. 또한 선언과 동시에 저장할 수 있는 타입이 결정됩니다. 만약 다른 타입의 값을 저장하려고 하면 타입 불일치(Type mismatch)컴파일 에러가 발생합니다.
② 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없습니다.
3개의 값을 저장하는 배열을 생성했다고 가정해보겠습니다. 프로그램 실행 도중에 5개의 값을 저장하는 배열로 수정할 수 없고, 반대로 2개의 값만 저장하는 배열로 수정할 수도 없습니다. 만약 5개의 값을 저장해야 하는 경우가 발생한다면 길이 5의 새로운 배열을 생성하고, 기존 배열 항목을 새 배열로 복사해야 합니다.
✅배열 선언
배열을 사용하기 위해서는 우선 배열 변수를 선언해야 합니다. 배열 변수 선언은 다음과 같이 두 가지 형식으로 작성할 수 있습니다.
형식 1 | 형식 2 | |
타입[] 변수; | 타입 변수[]; |
대괄호 [ ]는 배열 변수를 선언하는 기호로 사용되는데, 타입 뒤에 붙을 수도 있고 변수 뒤에 붙을 수도 있습니다. 타입은 배열에 저장될 데이터의 타입을 말합니다. 다음은 각 타입별로 배열을 선언하는 예입니다.
형식 1의 예 | 형식 2의 예 | |
int[] intArray; double[] doubleArray; String[] strArray; |
int intArray[]; double doubleArray[]; String strArray[]; |
배열 변수는 참조 변수에 속합니다. 배열도 객체이므로 힙 영역에 생성되고 배열 변수는 힙 영역의 배열 객체를 참조하게 됩니다. 만일 참조할 배열 객체가 없다면 배열 변수는 null 값으로 초기화될 수 있습니다.
타입[] 변수 = null;
만약 배열 변수가 null 값을 가진 상태에서 변수[인덱스]로 값을 읽거나 저장하게 되면 NullPointerException이 발생합니다. 배열을 생성하고 배열 변수가 참조하는 상태에서 값을 저장하거나 읽어야 합니다.
✅배열 생성
배열 객체를 생성하려면 값 목록을 이용하거나 new 연산자를 이용하는 방법이 있습니다.
✔️값 목록으로 배열 생성
값의 목록이 있다면 다음과 같이 간단하게 배열 객체를 생성할 수 있습니다.
타입[] 변수 = { 값0, 값1, 값2, 값3, … };
중괄호 { }는 주어진 값들을 항목으로 가지는 배열 객체를 힙에 생성하고, 배열 객체의 번지를 리턴합니다. 배열 변수는 리턴된 번지를 저장함으로써 참조가 이루어집니다. 예를 들어 “혼공자”, “혼공족장”, “자바맨” 문자열을 갖는 배열은 다음과 같이 생성할 수 있습니다.
String[ ] names = { “혼공자”, “혼공족장”, “자바맨” };
이렇게 생성된 배열에서 “혼공자”는 names[0], “혼공족장”은 names[1], “자바맨”는 names[2]로 읽을 수 있습니다. names[1]의 “혼공족장”을 “혼공족짱”으로 바꾸고 싶다면 다음과 같이 대입 연산자를 사용하면 됩니다.
names[1] = “혼공족짱”; |
값의 목록으로 배열 객체를 생성할 때 주의할 점이 있는데, 배열 변수를 이미 선언한 후에는 다른 실행문에서 중괄호를 사용한 배열 생성이 허용되지 않습니다.
타입[] 변수; 변수 = { 값0, 값1, 값2, 값3, … }; ← 컴파일 에러 |
배열 변수를 미리 선언한 후 값 목록들이 나중에 결정되는 상황이라면 다음과 같이 new 연산자를 사용해서 값 목록을 지정해주면 됩니다. new 연산자 바로 뒤에는 배열 변수 선언에서 사용한 “타입[ ]”를 붙여주고 중괄호 { }에는 값들을 나열해줍니다.
변수 = new 타입[] { 값0, 값1, 값2, 값3, … }; |
예를 들어 배열 names를 다음과 같이 생성할 수 있습니다.
String[] names = null;
names = new String[] { “혼공자”, “혼공족장”, “자바맨” };
메소드의 매개값이 배열일 경우에도 마찬가지입니다. 아래와 같이 매개 변수로 int[ ] 배열이 선언된 add( ) 메소드가 있을 경우, 값 목록으로 배열을 생성함과 동시에 add( ) 메소드의 매개값으로 사용하고자 할 때는 반드시 new 연산자를 사용해야 합니다.
int add(int[] scores) { … }
int result = add( {95, 85, 90} ); ← 컴파일 에러
int result = add( new int[] {95, 85, 90} );
✔️new 연산자로 배열 생성
값의 목록을 가지고 있지 않지만, 향후 값들을 저장할 배열을 미리 만들고 싶다면 new 연산자로 다음과 같이 배열 객체를 생성할 수 있습니다.
타입[] 변수 = new 타입[길이]; |
길이는 배열이 저장할 수 있는 값의 개수를 말합니다. 이미 배열 변수가 선언된 경우에도 new 연산자로 배열을 생성할 수 있습니다.
타입[] 변수 = null; 변수 = new 타입[길이]; |
다음은 길이가 5인 int[ ] 배열을 생성합니다.
int[] intArray = new int[5];
new 연산자로 배열을 처음 생성할 경우 배열은 자동적으로 기본값으로 초기화됩니다. 학생 30명의 점수를 저장할 배열을 다음과 같이 생성한다고 가정해보겠습니다. scores 배열은 int 배열이므로 다음과 같이 scores[0] ~ scores[29]까지 모두 기본값 0으로 초기화됩니다.
int[] scores = new int[30];
만약 String 배열을 생성했다면 names 배열의 경우 names[0] ~ names[29]까지 모두 null 값으로 초기화됩니다.
String[] names = new String[30];
✔️타입별 배열의 초기값
분류 | 타입 | 초기화 |
기본 타입(정수) | byte[] char[] short[] int[] long[] |
0 ‘\u000’ 0 0 0L |
기본 타입(실수) | float[ ] double[ ] |
0.0F 0.0 |
기본 타입(논리) | boolean[] | false |
참조 타입 | 클래스[ ] | null |
인터페이스[ ] | null |
배열이 생성되고 나서 특정 인덱스 위치에 새로운 값을 저장하려면 다음과 같이 대입 연산자를 사용하면 됩니다.
변수[인덱스] = 값; |
예를 들어 배열 scores의 0, 1, 2 인덱스에 각각 83, 90, 75를 저장하는 코드는 다음과 같습니다.
int[] scores = new int[3];
scores[0] = 83;
scores[1] = 90;
scores[2] = 75;
👀키워드로 보는 자바 배열의 핵심 포인트
- 배열: 같은 타입의 데이터를 연속된 공간에 나열하고, 각 데이터에 인덱스index를 부여해놓은 자료구조
- 인덱스: 배열 항목에 붙인 번호. 0번부터 시작하며 0~(배열길이–1)까지 범위를 가짐
- 배열 선언: 변수 선언과 비슷하며, 대괄호가 추가되어 타입[ ] 변수; 형태로 선언.
- int[ ] scores는 int 배열을 선언. 여기서 scores는 배열 변수
- 배열 생성: 배열을 생성하는 방법은 두 가지
- 하나는 { 값1, 값2, 값3, … }처럼 값 목록으로 생성하는 방법
- 다른 하나는 new 타입[길이];로 생성하는 방법
위 내용은 『혼자 공부하는 자바』의 일부분을 재구성하여 작성하였습니다.
핵심 내용 위주로 구성하여 이제 막 자바를 배우기 시작한 입문자도 포기하지 않고 완독할 수 있습니다. 자바 입문부터 복습까지, 혼자 공부하는 자바를 펼쳐보세요!
👀 도서 자세히 보기
✍️ 유튜브 강의
🙋 신용권 저자님께 질문하기
이 글 보고 공부하다 책을 바로 질렀습니다. 내일 받겠네요. 감사합니다.