Java_07) array - 배열
2025. 8. 26. 13:35

 

 

  • 배열의 개념과 필요성 이해
  • 배열의 선언, 생성, 초기화 방법
  • 배열과 메모리의 관계 파악
  • 얕은 복사와 깊은 복사의 차이점
  • 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