개요
배열이란 동일한 타입의 데이터 0개 이상을 하나의 연속된 메모리 공간에서 관리하는 것이다.
만약 동일한 타입인 여러개의 변수를 각각 생성하여 관리한다고 생각해 보자
그럼 변수의 개수가 증가 함으로서 자연스레 코드의 길이가 증가될 것이다.
또한 반복문을 적용하기가 불가능하며, 변수의 수가 동적으로 결정될 경우 사용할 수 없다.
따라서 배열을 통해 더욱 쉽고 편하게 변수를 관리할 수 있다.
다른 언어와 마찬가지로 배열은 한 번 생성되면 크기가 고정되며, 인덱스를 사용해 요소에 접근한다.
배열 선언
public class Main {
public static void main(String[] args) {
int[] numbers; // 권장 방식
int numbers2[]; // 가능하지만 권장되지 않음
}
}
C/C++에 익숙한 나로서 가장 익숙해지지 않는 부분이었다.
대체 왜 근본없게 변수명 뒤가 아닌 타입 뒤에 배열을 명시해 주는지는 이해가 잘 되지 않았다.
하지만 권장되지 않을 뿐 동작은 한다.
선언과 동시에 초기화를 할수도 있다.
public class Main {
public static void main(String[] args) {
int[] numbers = new int[5]; // 길이 5인 배열 생성 (기본값 0)
}
}
new 키워드를 사용해 배열을 생성하며, 초기값은 기본 타입의 기본값이다.
- int → 0
- double → 0.0
- boolean → false
- String(참조 타입) → null
배열 초기화
1. 명시적 초기화
int[] numbers = {1, 2, 3, 4, 5};
- 배열 선언과 동시에 값 초기화
- 크기 자동 설정: 초기 값의 개수만큼 배열의 길이가 자동으로 결정
- new 키워드를 사용하지 않아도 돼 간단하고 직관적
2. new와 함께 초기화
int[] numbers = new int[]{1, 2, 3, 4, 5};
- new 키워드 사용: 명시적으로 배열을 생성
- 초기 값을 지정하면서 크기 설정
- new int[] 부분을 사용하여 명확하게 배열을 생성
- 배열 초기화와 선언이 분리 가능
3. 차이점 정리
구분 | 명시적 초기화 | new와 함께 초기화 |
문법 | int[] arr = {1, 2, 3}; | int[] arr = new int[]{1, 2, 3}; |
배열 크기 설정 | 초기 값 개수에 맞게 자동 설정 | 초기 값 개수에 맞게 설정 |
new 사용 여부 | 사용 안 함 | 사용함 |
선언 후 초기화 가능 여부 | 불가능 | 가능 (new int[] 필수) |
유연성 | 선언과 동시에 초기화만 가능 | 선언 후 나중에 초기화 가능 |
간결성 | 더 간단하고 짧음 | 상대적으로 코드가 길어짐 |
4. 선언 후 초기화 가능 여부
❌ 명시적 초기화 (불가능)
int[] numbers;
numbers = {1, 2, 3}; // 컴파일 오류 발생
✅ new와 함께 초기화 (가능)
int[] numbers;
numbers = new int[]{1, 2, 3}; // 가능
5. 언제 사용해야 할까?
- 간단하게 초기화할 경우: 명시적 초기화 ({}) 사용
- 선언과 초기화를 나눠서 해야 하는 경우: new int[] 사용
- 동적으로 초기 값이 결정되는 경우: new int[] 방식이 필요
6. 예시: 동적 값 할당
int size = 5;
int[] numbers = new int[size]; // 동적으로 크기 결정 가능
- {} 방식은 동적 크기 할당이 불가능합니다.
- new를 사용해야 배열 크기를 변수로 설정할 수 있음
배열 사용 및 값 변경
int[] numbers = {10, 20, 30};
// 배열 값 읽기
System.out.println(numbers[0]); // 10
// 배열 값 변경
numbers[1] = 50;
System.out.println(numbers[1]); // 50
- 인덱스는 0부터 시작
- 존재하지 않는 인덱스에 접근하면 ArrayIndexOutOfBoundsException 발생
배열 반복문 활용
int[] numbers = {10, 20, 30, 40};
// 일반 for문
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
// 향상된 for문 (for-each)
for (int num : numbers) {
System.out.println(num);
}
- length: 배열의 길이를 반환
- for-each 문은 요소를 순차적으로 반복할 때 유용
다차원 배열
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 값 접근
System.out.println(matrix[1][2]); // 6
// 값 변경
matrix[2][1] = 15;
System.out.println(matrix[2][1]); // 15
배열 복사 및 크기 조절
1. System.arraycopy()
int[] original = {1, 2, 3};
int[] copy = new int[5];
System.arraycopy(original, 0, copy, 0, original.length);
- 배열 복사: original의 모든 요소를 copy에 복사
- 효율적이고 빠름
- 단, 배열의 크기를 벗어나는 행위를 저지르면 바로 에러를 뱉으니 조심하자
2. Arrays.copyOf()
import java.util.Arrays;
int[] numbers = {1, 2, 3};
int[] expanded = Arrays.copyOf(numbers, 5);
- 길이를 조절하며 복사 (5로 길이 증가)
- 만약 expanded의 크기를 2로 생성하면 크기에 맞게끔만 요소를 복사한다.
배열 유틸리티
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numbers = {3, 1, 4, 2};
// 배열 정렬
Arrays.sort(numbers); // {1, 2, 3, 4}
// 배열 출력
System.out.println(Arrays.toString(numbers)); // [1, 2, 3, 4]
// 배열 검색 (이진 탐색)
int index = Arrays.binarySearch(numbers, 3); // 2
}
}
- Arrays.sort(): 배열 정렬
- Arrays.binarySearch(): 이진 탐색 (정렬된 상태에서 사용)
- Arrays.toString(): 배열을 문자열로 출력
binarySearch메서드 사용 시 값이 존재하지 않는 경우 음수 값(-(삽입 위치 + 1))이 반환된다.
삽입 위치(Insertion Point)란 해당 값을 삽입할 적절한 위치를 의미한다.
가변 길이 리스트
자바 배열은 크기가 고정된다. 크기를 동적으로 변경하려면 ArrayList를 사용한다.
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.remove(0);
System.out.println(list); // [20]
}
}
가변 길이 리스트는 크기 조절 가능하며, 다양한 메서드 제공한다.
'웹(WEB) > 자바(JAVA)' 카테고리의 다른 글
[Java] 자바 변수의 선언 위치에 따른 분류 (0) | 2024.12.28 |
---|---|
[Java] 자바 JVM 메모리 구조 (0) | 2024.12.28 |
[Java] 자바 반복문 for, while, do while (0) | 2024.12.27 |
[Java] 자바 조건문 if, switch (1) | 2024.12.27 |
[Java] 자바 변수 타입, 타입 변환 (0) | 2024.12.27 |