배열(Array) 개념 및 사용법
프로그래밍에서 변수는 하나의 데이터만 저장할 수 있습니다. 하지만 많은 데이터를 처리해야 할 때, 일일이 변수를 사용하는 것은 비효율적입니다. 이 문제를 해결하기 위해 배열을 사용하면 데이터를 보다 쉽게 관리할 수 있습니다.
배열이란?
배열(Array)은 같은 타입의 데이터를 연속된 메모리 공간에 저장하는 자료구조입니다. 배열에 저장된 각각의 데이터는 요소(element)라고 하며, 요소의 위치는 인덱스(index)로 관리됩니다. 인덱스는 0부터 시작해서 배열의 크기 - 1까지의 값을 가집니다. 배열은 고정된 크기를 가지며, 초기화된 이후에는 크기를 변경할 수 없습니다.
배열의 특징
- 고정 크기 : 배열의 크기는 한 번 생성되면 변경할 수 없습니다. 크기를 변경하려면 새로운 배열을 생성한 후에 데이터를 복사해서 사용해야 합니다.
- 동일한 데이터 타입 : 배열과 동일한 데이터 타입만 저장할 수 있습니다. 다른 타입의 데이터를 저장하려 하면 컴파일 에러가 발생합니다.
- 빠른 인덱스 접근 : 배열의 각 요소는 인덱스를 통해 빠르게 접근할 수 있습니다. 이는 배열이 연속적인 메모리 공간에 저장되기 때문에 가능합니다.
배열의 선언과 생성
배열을 선언할 때에는 데이터 타입과 대괄호를 사용해서 배열임을 표시하고, 배열의 이름을 지정해줘야 합니다.
예를 들어, int 타입의 배열 numbers를 선언 및 생성할 때는 다음처럼 작성합니다. 배열을 선언한 후 나중에 배열을 초기화하려면 다음처럼 new 연산자를 사용해서 지정해 주면 됩니다.
// 배열 선언
int[] numbers;
// 배열 생성 및 초기화
int[] numbers = {1, 2, 3, 4, 5};
// 혹은 이렇게
numbers = new int[]{1, 2, 3, 4, 5};
배열 생성 시 기본 초기화 값
배열을 생성할 때는 각 요소가 자동으로 기본값으로 초기화됩나다. 아래 표는 데이터 타입에 따른 초기화 값을 정리한 내용입니다.
분류 | 타입 | 초기화 |
기본 타입(정수) | byte[] | 0 |
char[] | '\u000' | |
short[] | 0 | |
int[] | 0 | |
long[] | 0 | |
기본 타입(실수) | float[] | 0.0F |
double[] | 0.0 | |
기본 타입(논리) | boolean[] | false |
참조 타입 | 클래스[] | null |
인터페이스[] | null |
배열의 인덱스 접근
배열은 인덱스(Index)가 데이터를 저장한 순서대로 0부터 시작하며 1씩 증가됩니다. 이를 이용해서, 배열의 인덱스(Index)를 통해 각 요소에 접근할 수 있습니다.
String[] students = {"Kim", "Lee", "Choo", "Ji"};
String kim = students[0]; // "Kim"
배열의 요소는 인덱스를 통해 직접 변경이 가능합니다.
students[2] = "Bong";
log.info("student : {}", students[2]); // "Bong"
배열은 참조 타입으로 배열 변수가 참조하는 배열 객체의 주소값을 가지고 있습니다. 배열 변수의 인덱스 값을 변경한다면 해당 인덱스에 저장된 값이 변경되는 것이지, 참조하고 있는 배열 객체의 주소값은 변경되지 않습니다. 즉, 배열 변수의 인덱스 값을 변경한다고 해서 참조하고 있는 배열 객체의 주소값이 변경되지 않습니다. 배열 변수가 참조하는 배열 객체의 주소값은 배열 변수가 선언될 때 한 번 할당하고, 이후에는 변경되지 않습니다. 이 특성은 Java에서 참조 타입에 대한 기본 동작 방식입니다.
배열의 크기 확인
Java에서 배열의 크기를 확인하려면 length 메서드를 통해 확인할 수 있습니다. 배열의 final로 선언되어 있기 때문에 크기는 변경할 수 없으므로, length 필드의 값을 변경을 시도하게 되면 컴파일 오류가 발생합니다.
int[] numbers = {1, 2, 3, 4, 5};
System.out.print(numbers.length); // 5
2차원 배열
2차원 배열은 행(row)과 열(column)로 구성된 데이터를 저장하는 데 사용됩니다. 선언 시 1차원 배열과 마찬가지로 대괄호를 사용하지만, 2차원이므로 대괄호를 두 번 사용합니다. 메모리 용량이 허용하는 한 제한은 없지만 주로 1차원과 2차원 배열이 많이 사용됩니다.
// 2차원 배열 선언
int[][] numbers = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10}.
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20}
};
- 2차원 배열 출력
2차원 배열은 중첩 for문을 사용하거나 Arrays.deepToString() 메서드를 사용해서 배열의 모든 요소를 출력할 수 있습니다.
// 2중 for문으로 출력
for(int i = 0; i < numbers.length; i++) {
for(int j = 0; j < numbers[i].length; j++) {
System.out.println(numbers[i][j]);
}
}
// Arrays.deepToString 메서드 출력
System.out.println(Arrays.deepToString(numbers));
// 위 2중 for문과 Arrays.deepToString() 둘 다 같은 결과를 출력합니다.
// [1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20]
가변 배열
이차원 배열이 테이블 형태라고 하지만 반드시 행과 열이 균등할 필요가 없습니다. 자바에서 다차원 배열은 마지막 차수의 길이를 다르게 할 수 있기 때문에 각 요소로 들어가는 1차원 배열의 길이 달라도 이차원 배열을 생성할 수 있습니다. 그렇게 생성할 배열을 가변 배열이라고 합니다.
int[][] numbers = {
{1, 2, 3, 4, 5},
{6, 7},
{8, 9, 10},
{11, 12, 13},
{14, 15, 16, 17, 18, 19, 20}
};
배열의 메모리 구조
Java에서 배열은 객체로 취급되며, 배열 변수는 힙 영역에 생성된 배열 객체를 참조합니다. 배열을 생성하면 메모리의 힙 영역에 배열 객체가 할당되고, 배열 변수를 이 객체의 시작 주소를 가리키게 됩니다. 이때, 배열 변수가 참조할 배열 객체가 없을 경우, 배열 변수는 null로 초기화됩니다. 따라서 배열을 사용하기 전에는 반드시 배열 객체를 생성해야 하며, 그렇지 않으면 NullPointerException(NPE)가 발생합니다.
배열의 메모리 배치
Java의 배열은 메모리에 연속적으로 저장됩니다. 각 배열의 원소는 해당 데이터 타입의 크기만큼 메모리 공간을 차지하며, 인덱스에 따라 순서대로 저장됩니다. 예를 들어, int 배열의 첫 번째 원소는 4 바이트의 공간을 차지하고, 다음 원소들도 연속적으로 메모리 공간에 배치됩니다. 배열 변수 자체는 메모리의 스택(Stack) 영역에 저장됩니다. 스택은 함수 호출 시 사용되는 지역 변수와 함께 사용되며, 배열 변수는 배열 객체가 저장된 힙 영역의 주소를 가리키는 포인터 역할을 합니다. 배열의 인덱스를 통해 배열 원소에 접근할 때는 이 포인터를 기준으로 계산된 오프셋(offset)을 사용해서 배열 원소의 메모리 위치에 접근합니다.
배열 데이터의 힙 영역 저장 이유
배열 변수와 배열 데이터가 서로 다른 메모리 영역에 저장되는 이유는 Java가 객체지향 언어이기 때문입니다. 배열은 객체로 취급되며, 객체는 힙 영역에 동적으로 할당됩니다. 힙 영역에 배열 데이터를 저장함으로써 다음과 같은 이점이 있습니다:
- 다형성 지원: 배열 데이터가 객체로 취급되므로, 다양한 객체를 배열로 다룰 수 있습니다. 예를 들어, 여러 종류의 도형 객체를 하나의 배열에 담아 다형성을 구현할 수 있습니다.
- 동적 메모리 할당: 배열의 크기를 프로그램 실행 중에 동적으로 결정할 수 있어 유연한 메모리 관리가 가능합니다.
- 자동 메모리 관리: 힙 영역에 저장된 배열 데이터는 가비지 컬렉터에 의해 관리되므로, 메모리 누수나 불필요한 메모리 사용을 방지할 수 있습니다.
이러한 특성 덕분에 Java에서는 객체지향 프로그래밍의 다양한 장점을 배열을 통해서도 활용할 수 있습니다.
Ref.
[Java] 자바 배열(array) 선언하고 생성하기
배열: 같은 타입의 데이터를 연속된 공간에 나열하고, 각 데이터에 인덱스index를 부여해놓은 자료구조, 인덱스: 배열 항목에 붙인 번호. 0번부터 시작하며 0~(배열길이–1)까지 범위를 가짐, 배열
hongong.hanbit.co.kr
'🌈 프로그래밍 언어 > 자바' 카테고리의 다른 글
[Java] 변수의 스코프(Scope)와 형변환(Type Casting) 개념 정리 (0) | 2025.02.19 |
---|---|
[Java] 문자열 마스터하기 - String의 모든 것! (0) | 2024.09.10 |
[Java] 자바 반복문 - for, while, do-while 완벽 가이드 (0) | 2024.05.24 |
[Java] 자바 조건문(If문, Switch문) 가이드 (0) | 2024.05.19 |
[Java] 자바 연산자 Operator 가이드 정리 (0) | 2024.05.13 |