배열이란?
배열(Array)은 같은 타입의 데이터를 연속된 메모리 공간에 저장하는 자료구조입니다. 여러 개의 값을 하나의 변수로 관리할 수 있습니다.
학생 100명의 성적을 저장한다면? 변수 100개를 만드는 것보다 배열 하나로 관리하는 것이 훨씬 효율적입니다.
배열의 특징
| 특징 | 설명 |
|---|---|
| 같은 타입 | 배열의 모든 요소는 동일한 자료형 |
| 고정 크기 | 생성 시 크기가 결정되며, 변경 불가 |
| 인덱스 접근 | 0부터 시작하는 인덱스로 요소에 접근 |
| 연속 메모리 | 메모리에 연속적으로 저장 |
배열 scores (크기 5)
┌───────┬───────┬───────┬───────┬───────┐
│ 85 │ 90 │ 78 │ 92 │ 88 │
├───────┼───────┼───────┼───────┼───────┤
│ [0] │ [1] │ [2] │ [3] │ [4] │
└───────┴───────┴───────┴───────┴───────┘
인덱스 0부터 시작, 마지막 인덱스는 (크기-1)
1차원 배열
배열 선언
// 방법 1: 타입[] 배열명;
int[] scores;
String[] names;
// 방법 2: 타입 배열명[]; (C 스타일, 권장하지 않음)
int numbers[];
배열 생성
// 선언과 생성을 따로
int[] scores;
scores = new int[5]; // 크기가 5인 int 배열 생성
// 선언과 생성을 동시에
int[] numbers = new int[10]; // 크기가 10인 int 배열
String[] names = new String[3]; // 크기가 3인 String 배열
배열 초기화
// 방법 1: 선언, 생성, 초기화를 한 번에
int[] scores = {85, 90, 78, 92, 88};
// 방법 2: new 키워드와 함께 초기화
int[] scores = new int[]{85, 90, 78, 92, 88};
// 방법 3: 생성 후 개별 초기화
int[] scores = new int[5];
scores[0] = 85;
scores[1] = 90;
scores[2] = 78;
scores[3] = 92;
scores[4] = 88;
배열의 기본값
배열 생성 시 요소들은 자료형에 따라 기본값으로 초기화됩니다.
| 자료형 | 기본값 |
|---|---|
int, short, byte, long |
0 |
float, double |
0.0 |
char |
‘\u0000’ (널 문자) |
boolean |
false |
| 참조 타입 (String 등) | null |
int[] numbers = new int[3];
System.out.println(numbers[0]); // 0
String[] names = new String[3];
System.out.println(names[0]); // null
배열 요소 접근
int[] scores = {85, 90, 78, 92, 88};
// 읽기
System.out.println(scores[0]); // 85
System.out.println(scores[2]); // 78
// 쓰기
scores[1] = 95; // 90 → 95로 변경
System.out.println(scores[1]); // 95
배열 길이
length 속성으로 배열의 크기를 확인합니다.
int[] numbers = {10, 20, 30, 40, 50};
System.out.println(numbers.length); // 5
// 마지막 요소 접근
System.out.println(numbers[numbers.length - 1]); // 50
배열의 범위를 벗어난 인덱스에 접근하면 ArrayIndexOutOfBoundsException 오류가 발생합니다.
유효한 인덱스 범위: 0 ~ length - 1
int[] arr = {1, 2, 3};
System.out.println(arr[3]); // 오류! 유효 인덱스는 0, 1, 2
배열과 반복문
배열은 반복문과 함께 사용할 때 가장 강력합니다.
for 문으로 배열 순회
int[] scores = {85, 90, 78, 92, 88};
// 모든 요소 출력
for (int i = 0; i < scores.length; i++) {
System.out.println("scores[" + i + "] = " + scores[i]);
}
출력:
scores[0] = 85
scores[1] = 90
scores[2] = 78
scores[3] = 92
scores[4] = 88
배열 합계와 평균
int[] scores = {85, 90, 78, 92, 88};
int sum = 0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
double average = (double) sum / scores.length;
System.out.println("합계: " + sum); // 합계: 433
System.out.println("평균: " + average); // 평균: 86.6
최댓값과 최솟값
int[] numbers = {45, 78, 23, 91, 56};
int max = numbers[0];
int min = numbers[0];
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > max) {
max = numbers[i];
}
if (numbers[i] < min) {
min = numbers[i];
}
}
System.out.println("최댓값: " + max); // 91
System.out.println("최솟값: " + min); // 23
while 문으로 배열 순회
String[] fruits = {"사과", "바나나", "오렌지"};
int i = 0;
while (i < fruits.length) {
System.out.println(fruits[i]);
i++;
}
향상된 for 문 (for-each)
향상된 for 문은 배열의 모든 요소를 순차적으로 접근할 때 사용합니다. 인덱스 없이 요소에 직접 접근합니다.
기본 문법
for (자료형 변수명 : 배열명) {
// 변수명을 통해 요소에 접근
}
기본 예제
int[] scores = {85, 90, 78, 92, 88};
// 기존 for 문
for (int i = 0; i < scores.length; i++) {
System.out.println(scores[i]);
}
// 향상된 for 문 (for-each)
for (int score : scores) {
System.out.println(score);
}
합계 계산 (for-each)
int[] numbers = {10, 20, 30, 40, 50};
int sum = 0;
for (int num : numbers) {
sum += num;
}
System.out.println("합계: " + sum); // 합계: 150
for 문 vs for-each 비교
| 구분 | for 문 | for-each 문 |
|---|---|---|
| 인덱스 사용 | O | X |
| 요소 수정 | O | X (원본 수정 불가) |
| 가독성 | 보통 | 좋음 |
| 역순 순회 | O | X |
| 사용 시점 | 인덱스 필요, 요소 수정 | 단순 읽기 |
int[] arr = {1, 2, 3, 4, 5};
// for-each로 요소 수정 시도 (원본 변경 안 됨)
for (int num : arr) {
num = num * 2; // 지역 변수만 변경됨
}
System.out.println(arr[0]); // 1 (변경 안 됨)
// for 문으로 요소 수정 (원본 변경됨)
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i] * 2;
}
System.out.println(arr[0]); // 2 (변경됨)
단순히 배열의 모든 요소를 읽기만 한다면 for-each 문을 사용하세요. 코드가 간결해지고 실수를 줄일 수 있습니다.
다차원 배열
2차원 배열
2차원 배열은 배열의 배열입니다. 행(row)과 열(column)로 구성된 표 형태의 데이터를 저장합니다.
2차원 배열 (3행 4열)
열0 열1 열2 열3
┌─────┬─────┬─────┬─────┐
행0 │ 1 │ 2 │ 3 │ 4 │
├─────┼─────┼─────┼─────┤
행1 │ 5 │ 6 │ 7 │ 8 │
├─────┼─────┼─────┼─────┤
행2 │ 9 │ 10 │ 11 │ 12 │
└─────┴─────┴─────┴─────┘
2차원 배열 선언과 생성
// 선언
int[][] matrix;
// 생성 (3행 4열)
matrix = new int[3][4];
// 선언과 생성 동시에
int[][] table = new int[2][3];
2차원 배열 초기화
// 방법 1: 선언과 동시에 초기화
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 방법 2: 개별 요소 초기화
int[][] table = new int[2][3];
table[0][0] = 1;
table[0][1] = 2;
table[0][2] = 3;
table[1][0] = 4;
table[1][1] = 5;
table[1][2] = 6;
2차원 배열 요소 접근
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 읽기
System.out.println(matrix[0][0]); // 1 (0행 0열)
System.out.println(matrix[1][2]); // 6 (1행 2열)
System.out.println(matrix[2][1]); // 8 (2행 1열)
// 쓰기
matrix[1][1] = 100; // 5 → 100으로 변경
2차원 배열 길이
int[][] matrix = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
System.out.println(matrix.length); // 3 (행의 개수)
System.out.println(matrix[0].length); // 4 (0번 행의 열 개수)
System.out.println(matrix[1].length); // 4 (1번 행의 열 개수)
2차원 배열 순회
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 중첩 for 문
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
출력:
1 2 3
4 5 6
7 8 9
2차원 배열과 for-each
int[][] matrix = {
{1, 2, 3},
{4, 5, 6}
};
for (int[] row : matrix) { // 각 행
for (int value : row) { // 각 요소
System.out.print(value + " ");
}
System.out.println();
}
가변 배열 (Jagged Array)
Java의 2차원 배열은 각 행의 열 개수가 다를 수 있습니다.
// 가변 배열 생성
int[][] jagged = new int[3][];
jagged[0] = new int[2]; // 0행: 2열
jagged[1] = new int[4]; // 1행: 4열
jagged[2] = new int[3]; // 2행: 3열
// 가변 배열 초기화
int[][] jagged2 = {
{1, 2},
{3, 4, 5, 6},
{7, 8, 9}
};
// 순회
for (int i = 0; i < jagged2.length; i++) {
for (int j = 0; j < jagged2[i].length; j++) {
System.out.print(jagged2[i][j] + " ");
}
System.out.println();
}
출력:
1 2
3 4 5 6
7 8 9
Arrays 클래스
java.util.Arrays 클래스는 배열을 다루는 유용한 메서드를 제공합니다.
import java.util.Arrays;
toString() - 배열 출력
int[] arr = {3, 1, 4, 1, 5};
System.out.println(arr); // [I@hashcode (주소값)
System.out.println(Arrays.toString(arr)); // [3, 1, 4, 1, 5]
sort() - 정렬
int[] numbers = {5, 2, 8, 1, 9};
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers)); // [1, 2, 5, 8, 9]
// 부분 정렬 (인덱스 1부터 4 이전까지)
int[] arr = {5, 3, 1, 4, 2};
Arrays.sort(arr, 1, 4); // 인덱스 1, 2, 3만 정렬
System.out.println(Arrays.toString(arr)); // [5, 1, 3, 4, 2]
fill() - 값 채우기
int[] arr = new int[5];
Arrays.fill(arr, 7);
System.out.println(Arrays.toString(arr)); // [7, 7, 7, 7, 7]
// 부분 채우기
int[] arr2 = new int[5];
Arrays.fill(arr2, 1, 4, 9); // 인덱스 1~3만 9로 채움
System.out.println(Arrays.toString(arr2)); // [0, 9, 9, 9, 0]
copyOf() - 배열 복사
int[] original = {1, 2, 3, 4, 5};
// 같은 크기로 복사
int[] copy1 = Arrays.copyOf(original, original.length);
System.out.println(Arrays.toString(copy1)); // [1, 2, 3, 4, 5]
// 더 큰 크기로 복사 (나머지는 기본값)
int[] copy2 = Arrays.copyOf(original, 7);
System.out.println(Arrays.toString(copy2)); // [1, 2, 3, 4, 5, 0, 0]
// 더 작은 크기로 복사
int[] copy3 = Arrays.copyOf(original, 3);
System.out.println(Arrays.toString(copy3)); // [1, 2, 3]
copyOfRange() - 범위 복사
int[] arr = {1, 2, 3, 4, 5};
int[] part = Arrays.copyOfRange(arr, 1, 4); // 인덱스 1~3 복사
System.out.println(Arrays.toString(part)); // [2, 3, 4]
equals() - 배열 비교
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
int[] arr3 = {1, 2, 4};
System.out.println(arr1 == arr2); // false (주소 비교)
System.out.println(Arrays.equals(arr1, arr2)); // true (값 비교)
System.out.println(Arrays.equals(arr1, arr3)); // false
binarySearch() - 이진 검색
int[] arr = {1, 3, 5, 7, 9}; // 정렬된 상태여야 함
int index = Arrays.binarySearch(arr, 5);
System.out.println(index); // 2 (찾은 위치)
int notFound = Arrays.binarySearch(arr, 4);
System.out.println(notFound); // -3 (없으면 음수)
binarySearch()는 반드시 정렬된 배열에서만 사용해야 합니다. 정렬되지 않은 배열에서 사용하면 잘못된 결과가 나올 수 있습니다.
Arrays 메서드 요약
| 메서드 | 설명 |
|---|---|
toString(arr) |
배열을 문자열로 변환 |
sort(arr) |
오름차순 정렬 |
fill(arr, value) |
모든 요소를 지정 값으로 채움 |
copyOf(arr, length) |
배열 복사 (새 크기 지정 가능) |
copyOfRange(arr, from, to) |
범위 지정 복사 |
equals(arr1, arr2) |
두 배열 내용 비교 |
binarySearch(arr, key) |
이진 검색 (정렬 필수) |
배열 활용 예제
배열 역순 출력
int[] numbers = {1, 2, 3, 4, 5};
System.out.print("원본: ");
for (int num : numbers) {
System.out.print(num + " ");
}
System.out.print("\n역순: ");
for (int i = numbers.length - 1; i >= 0; i--) {
System.out.print(numbers[i] + " ");
}
출력:
원본: 1 2 3 4 5
역순: 5 4 3 2 1
배열 요소 검색
int[] numbers = {45, 78, 23, 91, 56};
int target = 23;
int foundIndex = -1;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == target) {
foundIndex = i;
break;
}
}
if (foundIndex != -1) {
System.out.println(target + "을 인덱스 " + foundIndex + "에서 찾았습니다.");
} else {
System.out.println(target + "을 찾지 못했습니다.");
}
// 출력: 23을 인덱스 2에서 찾았습니다.
배열 요소 개수 세기
int[] scores = {85, 90, 78, 92, 88, 95, 72, 90};
int target = 90;
int count = 0;
for (int score : scores) {
if (score == target) {
count++;
}
}
System.out.println(target + "점을 받은 학생: " + count + "명");
// 출력: 90점을 받은 학생: 2명
2차원 배열 합계
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int total = 0;
for (int[] row : matrix) {
for (int value : row) {
total += value;
}
}
System.out.println("전체 합계: " + total); // 전체 합계: 45
종합 실습
문제 1 - 배열 기초 (기초)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
int[] arr = {10, 20, 30, 40, 50};
System.out.println(arr[2]);
}
}
문제 2 - 배열 길이 (기초)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
String[] fruits = {"사과", "바나나", "오렌지", "포도"};
System.out.println(fruits.length);
}
}
문제 3 - 배열 합계 (기초)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
int[] nums = {1, 2, 3, 4, 5};
int sum = 0;
for (int n : nums) {
sum += n;
}
System.out.println(sum);
}
}
문제 4 - 2차원 배열 (중급)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
int[][] arr = {
{1, 2, 3},
{4, 5, 6}
};
System.out.println(arr[1][2]);
}
}
문제 5 - 배열 기본값 (중급)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
int[] arr = new int[3];
arr[1] = 5;
int sum = arr[0] + arr[1] + arr[2];
System.out.println(sum);
}
}
문제 6 - 2차원 배열 길이 (중급)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
int[][] matrix = new int[3][4];
System.out.println(matrix.length + matrix[0].length);
}
}
문제 7 - Arrays 클래스 (고급)
다음 Java 프로그램의 실행 결과는 무엇입니까?
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
int[] arr = {5, 2, 8, 1, 9};
Arrays.sort(arr);
System.out.println(arr[2]);
}
}
문제 8 - 가변 배열 (고급)
다음 Java 프로그램의 실행 결과는 무엇입니까?
public class Test {
public static void main(String[] args) {
int[][] arr = {
{1, 2},
{3, 4, 5, 6},
{7, 8, 9}
};
int sum = 0;
for (int[] row : arr) {
sum += row.length;
}
System.out.println(sum);
}
}
실전 프로그래밍
과제 1: 성적 처리 프로그램
학생 5명의 성적을 배열에 저장하고 합계, 평균, 최고점, 최저점을 구하는 프로그램을 작성하세요.
요구사항:
- 5명의 성적을 배열에 저장 (예: 85, 92, 78, 96, 88)
- 합계, 평균, 최고점, 최저점 계산
- 결과 출력
예시 답안 보기
public class GradeProcessor {
public static void main(String[] args) {
int[] scores = {85, 92, 78, 96, 88};
int sum = 0;
int max = scores[0];
int min = scores[0];
for (int score : scores) {
sum += score;
if (score > max) max = score;
if (score < min) min = score;
}
double average = (double) sum / scores.length;
System.out.println("===== 성적 처리 결과 =====");
System.out.println("합계: " + sum);
System.out.printf("평균: %.2f\n", average);
System.out.println("최고점: " + max);
System.out.println("최저점: " + min);
}
}
출력:
===== 성적 처리 결과 =====
합계: 439
평균: 87.80
최고점: 96
최저점: 78
과제 2: 배열 정렬 (버블 정렬)
Arrays.sort()를 사용하지 않고 버블 정렬 알고리즘으로 배열을 오름차순 정렬하는 프로그램을 작성하세요.
요구사항:
- 정렬할 배열 선언 (예: {64, 34, 25, 12, 22, 11, 90})
- 버블 정렬: 인접한 두 요소를 비교하여 교환
- 정렬 전후 배열 출력
예시 답안 보기
import java.util.Arrays;
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {64, 34, 25, 12, 22, 11, 90};
System.out.println("정렬 전: " + Arrays.toString(arr));
// 버블 정렬
for (int i = 0; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// 교환
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println("정렬 후: " + Arrays.toString(arr));
}
}
출력:
정렬 전: [64, 34, 25, 12, 22, 11, 90]
정렬 후: [11, 12, 22, 25, 34, 64, 90]
과제 3: 행렬 덧셈
두 개의 2차원 배열(행렬)을 더하는 프로그램을 작성하세요.
요구사항:
- 같은 크기의 2×3 행렬 두 개 선언
- 두 행렬의 같은 위치 요소끼리 더하기
- 결과 행렬 출력
예시 답안 보기
public class MatrixAddition {
public static void main(String[] args) {
int[][] matrix1 = {
{1, 2, 3},
{4, 5, 6}
};
int[][] matrix2 = {
{7, 8, 9},
{10, 11, 12}
};
int[][] result = new int[2][3];
// 행렬 덧셈
for (int i = 0; i < matrix1.length; i++) {
for (int j = 0; j < matrix1[i].length; j++) {
result[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
// 결과 출력
System.out.println("===== 행렬 덧셈 결과 =====");
for (int[] row : result) {
for (int value : row) {
System.out.print(value + "\t");
}
System.out.println();
}
}
}
출력:
===== 행렬 덧셈 결과 =====
8 10 12
14 16 18
핵심 요약
이번 챕터에서 배운 내용
- 배열 선언과 생성
int[] arr = new int[5]; // 생성 int[] arr = {1, 2, 3, 4, 5}; // 초기화 - 배열 접근
arr[0] = 10; // 쓰기 int value = arr[0]; // 읽기 int size = arr.length; // 길이 - 향상된 for 문
for (int num : arr) { // 요소 읽기 전용 } - 2차원 배열
int[][] matrix = new int[3][4]; // 3행 4열 matrix[0][0] = 1; // 요소 접근 matrix.length; // 행 개수 matrix[0].length; // 열 개수 - Arrays 클래스 주요 메서드
메서드 기능 toString()배열 → 문자열 sort()정렬 fill()값 채우기 copyOf()배열 복사 equals()배열 비교 - 주요 포인트
- 인덱스는 0부터 시작, 마지막은
length - 1 - 범위 초과 시 ArrayIndexOutOfBoundsException
- 배열 크기는 생성 후 변경 불가
- for-each는 읽기 전용, 요소 수정 불가
- 2차원 배열은 행별로 다른 열 개수 가능 (가변 배열)
- 인덱스는 0부터 시작, 마지막은
다음 챕터 예고
다음 챕터에서는 클래스와 객체를 배웁니다.
- 클래스와 객체 개념
- 접근 제어자
- 메서드 정의 및 호출
- 생성자 및 생성자 오버로딩
- 상속 및 super 키워드
배열 학습 완료!
여러 데이터를 효율적으로 관리하는 배열을 배웠습니다.
이제 메서드를 배우면 코드를 재사용 가능한 단위로 구성할 수 있습니다!