- 배열의 개념과 필요성 이해
- 배열의 선언, 생성, 초기화 방법
- 배열과 메모리의 관계 파악
- 얕은 복사와 깊은 복사의 차이점
- for-each문을 활용한 배열 순회
- 배열을 활용한 실전 문제 해결
<배열>
변수 vs 배열
변수는 하나의 공간에 하나의 값을 담을 수 있으며, 메모리 공간에 이름을 붙여서 사용한다.
배열은 하나의 이름(참조변수)에 여러 개의 같은 자료형의 값을 저장할 수 있는 연속적인 메모리 공간이다.
배열을 사용하는 이유
변수만을 사용하면 대량의 데이터를 보관하고자 할 때 각각의 변수를 만들어서 따로 관리해야 한다. 배열을 이용하면 한번에 관리할 수 있다.
예시 비교:
// 변수 사용
int num1 = 0, num2 = 1, num3 = 2, num4 = 3, num5 = 4;
// 배열 사용
int[] arr = {0, 1, 2, 3, 4};
배열의 선언과 생성
1. 배열 선언
자료형[] 배열이름;
배열의 참조 변수만 생성되며, 아직 실제 메모리는 할당되지 않는다.
int[] iArr1; // 배열의 참조 변수만 생성
2. 배열 생성 (메모리 할당)
배열이름 = new 자료형[길이];
지정된 길이만큼의 메모리 공간이 할당된다.
iArr1 = new int[10]; // 10개의 int 공간 할당
3. 배열 초기화 방법
방법 1: 선언과 생성을 분리
int[] iArr1;
iArr1 = new int[10];
// 반복문을 통한 값 할당
for(int i = 0; i < iArr1.length; i++) {
iArr1[i] = i;
}
방법 2: 선언과 동시에 초기화
int[] arr2 = {0, 1, 2, 3, 4};
4. 배열 출력 방법
일반 for문 사용
for(int i = 0; i < iArr1.length; i++) {
System.out.print(iArr1[i] + " ");
}
for-each문 사용
for(int num : iArr1) {
System.out.println(num + "을 가져옴");
}
for-each문 구조:
for(배열의 값을 받아줄 변수 : 배열) {
반복할 코드
}
배열 메모리 구조 이해
기본 자료형 vs 참조 자료형
기본 자료형(원시타입): int, double, float, char, long 등
- 실제 리터럴 값을 바로 담을 수 있다
참조 자료형: String, Scanner, int[], double[] 등
- 필요한 메모리의 크기가 가변적이기 때문에 주소값을 담는다
배열의 메모리 구조
package com.kh.array;
public class ArrayMemory {
public static void main(String[] args) {
int i = 10;
int[] iArr = new int[5];
// 배열의 주소값 확인
System.out.println(iArr.hashCode());
// 배열 생성 시 기본값으로 초기화됨
for(int num = 0; num < iArr.length; num++) {
System.out.print(iArr[num]); // 0 0 0 0 0
}
}
}
중요한 개념들:
- 배열 생성 시 기본값으로 자동 초기화됨 (int: 0, double: 0.0, boolean: false)
- Heap 메모리 공간은 절대 빈 공간을 허용하지 않음
- 배열은 한번 크기가 정해지면 변경 불가능
배열 크기 변경의 한계
int[] arr = new int[5];
System.out.println(arr.hashCode()); // 주소값1
arr = new int[10]; // 새로운 메모리 공간 할당
System.out.println(arr.hashCode()); // 주소값2 (다른 값)
기존 배열이 수정되는 것이 아니라 새로운 메모리 공간을 할당받는다. 연결이 끊어진 기존 배열은 **GC(가비지컬렉터)**가 자동으로 회수한다.
배열 복사 방법
1. 얕은 복사 (Shallow Copy)
주소값만 복사하여 같은 메모리 공간을 참조한다.
int[] origin = {1, 2, 3, 4, 5};
int[] copy = origin; // 얕은 복사
copy[2] = 99;
// origin과 copy 모두 영향받음 (같은 메모리 참조)
2. 깊은 복사 (Deep Copy)
방법 1: for문 활용
int[] origin2 = {1, 2, 3, 4, 5};
int[] copy2 = new int[origin2.length];
for(int i = 0; i < copy2.length; i++) {
copy2[i] = origin2[i];
}
copy2[2] = 99;
// origin2와 copy2는 서로 독립적
방법 2: clone() 메서드 활용
int[] origin3 = {1, 2, 3, 4, 5};
int[] copy3 = origin3.clone();
copy3[2] = 99;
// origin3와 copy3는 서로 독립적 (기본형 배열의 경우)
clone() 메서드 특징:
- Java에서 제공하는 메서드
- 기본적으로 얕은 복사를 진행하지만, 기본형 배열(원시타입)은 깊은 복사로 동작
예제 1: 기본 배열 조작
package com.kh.array;
import java.util.Scanner;
public class ArrayTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 1. 크기가 10인 정수형 배열 생성
int[] iArr = new int[10];
// 2. 모든 요소를 10으로 초기화
for(int i = 0; i < iArr.length; i++) {
iArr[i] = 10;
}
// 3. for-each를 사용하여 모든 요소 출력
for(int i : iArr) {
System.out.print(i + " ");
}
System.out.println();
sc.close();
}
}
예제 2: 동적 배열 생성과 문자열 검색
// 4. 사용자에게 배열의 길이를 입력받아 문자열 배열 생성
System.out.print("배열의 길이 입력: ");
int num = sc.nextInt();
String[] nameArr = new String[num];
// 5. 사용자에게 이름을 입력받아 배열에 할당
for(int i = 0; i < nameArr.length; i++) {
System.out.print("이름 입력: ");
nameArr[i] = sc.next();
}
// 6. 특정 이름 검색
System.out.print("비교할 이름 입력: ");
String name = sc.next();
boolean found = false;
for(String s : nameArr) {
if(s.equals(name)) {
found = true;
break;
}
}
System.out.println(found ? "동일한 이름이 존재합니다." : "동일한 이름이 존재하지 않습니다.");
실행 결과:
배열의 길이 입력: 3
이름 입력: 김철수
이름 입력: 이영희
이름 입력: 박민수
비교할 이름 입력: 이영희
동일한 이름이 존재합니다.
배열과 참조변수 비교
배열 비교 시 주의사항
int[] arr4 = {1, 1, 1, 1, 1};
int[] arr5 = {1, 1, 1, 1, 1};
System.out.println(arr4 == arr5); // false
// 참조변수는 ==로 비교 시 주소값을 비교하기 때문
arr4 = arr5;
System.out.println(arr4 == arr5); // true
// 이제 같은 메모리를 참조
null 처리
int[] arr = new int[5];
arr = null; // 배열을 더 이상 사용하지 않을 때 메모리 반환
// arr.length; // NullPointerException 발생
배열의 특징:
- 같은 자료형의 데이터를 연속적으로 저장
- 한번 크기가 정해지면 변경 불가능
- 인덱스는 0부터 시작
- 생성 시 기본값으로 자동 초기화
메모리 구조:
- 참조변수는 배열의 주소값을 저장
- 실제 데이터는 Heap 영역에 저장
- GC가 사용되지 않는 메모리를 자동 회수
복사 방식:
- 얕은 복사: 주소값 복사 (같은 메모리 참조)
- 깊은 복사: 새로운 메모리 공간에 값 복사 (독립적)
배열 순회:
- 일반 for문: 인덱스가 필요한 경우
- for-each문: 모든 요소를 순차적으로 접근하는 경우
'Java' 카테고리의 다른 글
| Java_09) Method (4) | 2025.08.27 |
|---|---|
| Java_08) 다차원 배열 (6) | 2025.08.26 |
| Java_06) Loop - 반복문 (4) | 2025.08.26 |
| Java_05) Control - 조건문(제어문) (1) | 2025.08.26 |
| Java_04 ) Operator 연산자 (0) | 2025.08.21 |