포스트

배열이란 무엇인가

배열이 무엇인지부터 자바에서의 선언, 생성, 사용법, 주의할 점까지 예제와 함께 정리한 학습 글이다.

배열이란 무엇인가

1. 배열이란?

배열(Array)은 같은 자료형의 값을 여러 개 묶어서 전장하는 구조이다.
예를 들어 학생 점수 5개를 저장해야 한다고 하면, 변수 5개를 따로 만드는 대신 배열 하나로 관리할 수 있게된다.

자바 배열은 인덱스(index) 로 각 값을 구분하며, 인덱스는 0부터 시작한다.
또 한 번 생성하게 되면 크기를 바꿀 수 없다는 점이 핵심 특징이다.

처음 배열을 배울 때는 그냥 “값 여러 개 넣는 통”처럼 보이는데, 실제로는 단순 저장 이상의 의미가 있다.
배열은 데이터를 순서 있게 보관하고, 같은 타입끼리 일관성 있게 처리하게 해준다. 그래서 반복문과 함께 쓰이면 굉장히 강력하다.

예를 들어 점수를 관리한다고 해보자.

1
int[] scores = {88, 92, 75, 64, 100};

이제 scores[0], scores[1]처럼 각 값에 접근할 수 있다.
즉, 배열은 “여러 값을 하나의 이름 아래에서 관리하는 방식”이라고 보면 된다.


2. 배열은 어떻게 선언하고 생성하는가

배열을 사용할 때는 보통 선언 → 생성 → 초기화 흐름으로 이해하면 쉽다.
배열 선언은 “이런 타입의 배열을 쓰겠다”는 뜻이고, 생성은 “실제로 몇 칸짜리 공간을 만들겠다”는 뜻이다.

선언만 하면 아직 저장 공간은 없는 상태고, new를 사용해야 실제 배열이 만들어진다.
자바에서 배열은 new로 생성되며, 생성 후 크기는 고정된다. 또한 기본형 배열의 값은 0, boolean은 false, 참조형은 null로 자동 초기화된다.

예를 들어

1
2
int[] numbers; // 선언 
numbers = new int[4]; // 생성

이렇게 하면 정수 4개를 저장할 수 있는 배열이 만들어진다.
이 시점의 numbers안에는 아직 내가 넣은 값은 없지만, 자바가 기본으로 채워 넣는다.

1
2
System.out.println(numbers[0]); // 0
System.out.println(numbers[1]); // 0

이 부분에서 중요한 건, 배열은 생성 순간 크기가 정해진다는 점이다.
즉, new int[4]로 만들면 끝가지 4칸짜리가 되는 것이다. 나중에 값이 더 필요하다고 해서 자동으로 늘어나지 않는다.

이 특성은 장점과 단점이 동시에 존재한다.

  • 장점: 구조가 단순하고 예측 가능하다.
  • 단점: 유연하게 늘어나지 않는다.

그래서 배열은 “개수가 정해진 데이터”를 다룰 때 특히 잘 맞는다.


3. 배열을 실제로 어떻게 사용하는가

배열의 핵심 사용법은 크게 세 가지다.

  • 값 넣기
  • 값 꺼내기
  • 전체 순회하기

배열의 요소는 인덱스로 접근하고 수정할 수 있으며, 전체 요소를 다룰 때는 반복문과 length를 함께 사용한다.
배열의 크기는 length로 확인한다.

3-1. 값 넣기와 꺼내기

1
2
3
4
5
6
String[] menu = new String[3];
menu[0] = "김치찌개";
menu[1] = "된장찌개";
menu[2] = "순두부찌개";

  System.out.println(menu[1]); // 된장찌개

여기서 menu[1]은 두 번째 요소이다.
배열은 1부터가 아닌 0부터 시작하므로, 이 부분은 처음 배우게 된다면 헷갈릴 수 있다.

3-2. 값 수정하기

1
2
menu[2] = "부대찌개";
System.out.println(menu[2]); // 부대찌개

배열은 크기를 못 바꾸지만, 기존 칸의 값은 바꿀 수 있다.

3-3. 전체 순회하기

배열을 쓰는 진짜 이유는 반복문을 만났을 때 드러난다.

1
2
3
4
5
int[] nums = {3, 6, 8, 12};

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

여기서 nums.length는 배열 길이이고, 인덱스 범위는 0부터 length - 1까지다.
즉 길이가 4면 인덱스는 0, 1, 2, 3이 된다.

배열을 반복문으로 순회하는 건 합계, 평균, 최댓값, 최소값처럼 여러 값을 한 번에 계산하는 기본 패턴이 여기서 시작된다고 보면 된다.

예를 들면

1
2
3
4
5
6
7
8
int[] scores = {80, 90, 100};
int sum = 0;

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

System.out.println("총합:  + sum");

배열은 단순 문법이 아닌, 반복 처리의 출발점이라고 보는 게 좋을 것 같다.


4. 배열을 공부할 때 꼭 이해해야 하는 핵심 포인트

배열은 문법 자체는 어렵지 않지만, 몇 가지를 정확히 이해하지 않으면 계속 헷갈릴 수 있다.

4-1. 배열의 길이와 마지막 인덱스는 다르다

💡중요

1
int[] arr = new int[5];

이 배열의 길이는 5이지만, 마지막 인덱스는 5가 아닌 4가 된다.

왜냐하면 시작이 0이기 때문이다.

  • 첫 번째 칸 → arr[0]
  • 두 번째 칸 → arr[1]
  • 세 번째 칸 → arr[2]
  • 네 번째 칸 → arr[3]
  • 다섯 번째 칸 → arr[4]

4-2. 범위를 벗어나면 예외가 발생한다

자바 배열은 존재하지 않는 칸에 접근하면 ArrayIndexOutOfBoundsException이 발생한다.
즉 인덱스가 음수이거나, 배열 길이 이상이면 오류가 난다.

예시

1
2
int[] arr = {10, 20, 30};
System.out.println(arr[3]); // 예외 발생

유효한 인덱스는 0, 1, 2뿐인데 3에 접근했기 때문이다.

이 예외가 자주 발생하는 이유는 보통 두 가지다.

  1. 반복문 조건을 잘못 쓴 경우
  2. 배열 길이와 인덱스를 혼동한 경우

그래서 배열을 다룰 때는 항상 이 기준을 머릿속에 넣어두면 좋다.

1
0 <= index < arr.length

4-3. 배열은 같은 타입만 저장할 수 있다

배열은 같은 자료형만 저장한다.
즉 정수 배열에는 정수만 넣어야 하고, 문자열 배열에는 문자열만 넣어야 한다.

1
2
int[] arr = {1, 2, 3}; // 가능
String[] names = {"철수", "영희"}; // 가능

하지만 아래처럼 섞어 놓는 개념은 허용되지 않는다.

1
2
// 불가능한 개념 
// int[] arr = {1, "hello", 3};

이 특징은 불편해 보일 수도 있지만, 반대로 생각하면 타입이 명확해서 코드가 안정적이다.


4-4. 객체 배열은 객체 자체가 아니라 참조를 저장한다

배열에는 기본형뿐 아니라 객체도 담을 수 있다.
그런데 객체 배열은 객체를 통쨰로 저장한느 게 아니라 객체를 가리키는 참조값을 저장한다.

예를 들어

1
2
3
4
5
6
7
class Student {
    String name;
    
    Student(String name) {
        this.name = name;
    }
}
1
2
3
Student[] students = new Student[2];
students[0] = new Student("민수");
students[1] = new Student("지연");

여기서 new Student[2]는 Student객체 2개를 만든 것이 아닌, Student를 참조할 수 있는 칸 2개를 만든 것이다.
그래서 각 칸에 다시 new Student(...)를 넣어줘야 한다.

이 부분을 놓치면 아래 같은 실수를 하게 된다.

1
2
Student[] students = new Student[2];
System.out.println(students[0].name); // null 관련 오류 가능

왜냐하면 아직 students[0]에 실제 Student 객체를 넣지 않았기 때문이다.


5. 배열과 메서드는 어떻게 연결되는가

배열은 변수처럼 메서드에 전달할 수 있고, 메서드에서 배열을 반환할 수도 있다.
이것은 배열을 단순 저장 용도가 아닌, 기능 단위로 분리해서 처리할 수 있게 해준다는 점에서 중요하다.

예를 들어 배열의 총합을 구하는 메서드를 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
    public static void main(String[] args) {
        int[] prices = {1000, 2000, 3000};
        printTotal(prices);
    }
    
    public static void printTotal(int[] arr) {
        int total = 0;
        for (int i = 0; i < arr.length; i++) {
            total += arr[i];
        }
        System.out.println("총합: " + total);
    }
}

이렇게 하면 배열을 직접 처리하는 로직을 메서드로 분리할 수 있다.
즉, 코드가 더 읽기 쉬워지고 재사용하기도 쉬워진다.

반대로 메서드가 배열을 만들어서 반환할 수도 있다.

1
2
3
public static int[] makeArray() {
    return new int[]{1, 2, 3, 4};
}

이런 방식은 여러 값을 한 번에 전달하고 싶을 때 유용하다.


6. 배열의 장점과 한계

배열은 가장 기본적인 자료구조인 만큼 장점도 분명하고 한계도 분명하다.

배열의 장점은 인덱스로 바로 접근할 수 있고 빠르다는 점이고, 단점은 크기가 고정되어 있고 중간 삽입/삭제가 비효율적이라는 점이다.

장점

  1. 인덱스로 바로 접근하므로 속도가 빠름
    • 예) 100개의 값이 있어도 arr[50]처럼 바로 접근할 수 있다.
  2. 반복문과 궁합이 좋다.
    • 합계, 평균, 탐색, 최댓값 찾기 같은 문제를 다룰 때 배열은 거의 필수적이다.

단점

  1. 크기가 고정된다.
    • 처음에 너무 작게 만들면 부족하고, 너무 크게 만들면 공간이 남게된다.
  2. 중간 삽입/삭제가 불편하다.
    • 예) 중간에 값을 끼워 넣으려면 뒤 요소들은 한 칸씩 밀어야 한다.

위와 같은 이유들로 배열과 ArrayList를 상황에 맞게 구분해서 사용한다.


정리

배열은 자바에서 가장 먼저 배우는 자료구조이지만, 뒤로 갈수록 더 중요해지는 것 같다.
반복문, 객체, 메서드, 자료구조, 알고리즘까지 전부 배열 개념 위에서 확장되기 때문이다.

배열을 공부하면서 꼭 잡아야 할 핵심은 아래와 같다고 생각한다.

  • 배열은 같은 타입의 값을 묶어 저장한다.
  • 인덱스는 0부터 시작한다.
  • 생성 후 크기는 바꿀 수 없다.
  • length로 길이를 확인한다.
  • 반복문과 함께 많이 사용한다.
  • 객체 배열은 참조를 저장한다.
  • 범위를 벗어나면 예외가 발생한다.

이 정도를 정확히 이해한다면, ArrayList, 2차원 배열, 자료구조 문제도 수월해질거라 생각한다.

참고 문서

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.