본문 바로가기

멋쟁이사자처럼_부트캠프/Java

[멋쟁이사자처럼 부트캠프 TIL 회고] 백엔드 부트캠프 13기: Java 3일차 Java의 배열, for-each문, 그리고 Arrays api

배열

같은 타입의 데이터를 연속적으로 저장할 수 있는 자료구조. 배열은 고정된 크기를 가지며, 각 요소는 인덱스를 통해 접근할 수 있음.

Java에서 배열과 배열의 값들은 각각 다른 메모리 영역에 저장됨.

 

1. 배열의 특징

힙 메모리에 저장:

  • 배열은 객체로 힙(Heap) 메모리에 저장되며, 참조를 통해 접근함.
  • (자바 메모리 구조의 다른 부분인 스택영역에는 메서드 호출 시 생성되는 지역 변수, 참조 변수 등이 저장됨. 배열 이름(str[])도 참조 변수로 스택에 저장됨.)

2. 배열 선언과 초기화

배열 선언

배열을 선언하려면 **데이터 타입 뒤에 대괄호([])**를 사용함:

int[] numbers; // 정수형 배열 선언 String[] names; // 문자열 배열 선언

배열 생성

배열을 생성하려면 new 키워드와 크기를 지정해야 함:

numbers = new int[5]; // 길이가 5인 정수형 배열 생성

선언과 생성을 동시에

int[] numbers = new int[5]; // 크기가 5인 배열 선언 및 생성

초기화

배열 생성 시 기본값으로 초기화되거나, 값을 직접 할당할 수 있음:

int[] numbers = new int[5];      // 1. 기본값으로 초기화 // {0, 0, 0, 0, 0} 
int[] numbers = {1, 2, 3, 4, 5}; // 2. 직접 초기화 // {1, 2, 3, 4, 5}

배열의 크기

배열의 크기는 .length를 사용해 얻을 수 있음:

int[] numbers = {1, 2, 3}; System.out.println(numbers.length); // 출력: 3

 

4. 배열 반복문

향상된 for문 (Enhanced for Loop)

int[] numbers = {1, 2, 3, 4, 5}; for (int num : numbers) { System.out.println(num); }

5. 다차원 배열

2차원 배열 선언과 생성

int[][] matrix = new int[2][3]; // 2행 3열 배열 생성

2차원 배열 초기화

int[][] matrix = { {1, 2, 3}, {4, 5, 6} };

2차원 배열 접근

 

6. 배열의 장점과 단점

장점

  1. 빠른 데이터 접근:
    • 인덱스를 통해 O(1) 시간 복잡도로 접근 가능.
  2. 메모리 연속성:
    • 배열 요소는 메모리에 연속적으로 저장되어 효율적.

단점

  1. 고정 크기:
    • 크기가 고정되므로 크기 변경이 필요한 경우 새로운 배열 생성 필요.
  2. 동적 데이터 관리 어려움:
    • 추가/삭제가 빈번한 경우 ArrayList와 같은 동적 자료구조를 사용하는 것이 더 적합.

7. 요약

  1. 배열 선언: 타입[] 변수명;
  2. 배열 생성: new 타입[크기];
  3. 배열 접근: 배열[인덱스]
  4. 배열 반복: for 또는 향상된 for 사용.

배열은 고정 크기의 동일 타입 데이터 관리에 적합한 자료구조.

동적으로 크기를 변경하거나 유연하게 데이터를 추가/삭제하려면 ArrayList와 같은 컬렉션 사용을 고려해야 함.


1. int[ ] arr1 = { };

  • 배열 선언과 동시에 초기화:
    • 길이가 0인 배열을 생성하고 참조 변수 arr1에 할당.
    • 이 배열은 힙 메모리에 생성되며, 실제로 아무 요소도 없음.
  • 메모리 상태:
    • arr1은 스택에 저장되고, 길이가 0인 배열은 힙에 저장됨.
  • 유효한 코드:
    • 이 방식은 빈 배열을 생성하는 데 사용됨.
int[] arr1 = {}; // 길이가 0인 배열 System.out.println(arr1.length); // 출력: 0

2. int[ ] arr2;

  • 배열 참조 변수만 선언:
    • 배열 객체를 생성하지 않음.
    • arr2는 스택에 선언되지만, 초기화되지 않음.
    • 따라서 null 값을 가짐(로컬 변수일 경우 초기화하지 않으면 사용 시 컴파일 오류).
  • 메모리 상태:
    • arr2는 배열 객체를 참조할 준비만 되어 있고, 아무 것도 가리키지 않음.
  • 초기화 필요:
    • 배열을 사용하려면 반드시 배열 객체를 생성하거나 초기화해야 함.
int[] arr2; // 선언만 
arr2 = 
new int[5]; // 배열 객체 생성 
System.out.println(arr2.length); 
// 출력: 5

차이점 요약


유효성 확인

  • arr1 사용 가능:
    • arr1은 길이가 0인 배열을 참조하므로 배열 연산이 가능.
  • arr2 초기화 필요:
    • arr2를 사용하려면 먼저 배열 객체를 생성하거나 참조를 할당해야 함.

예제

 

결론

  • arr1 = {};: 길이가 0인 배열로 초기화된 상태.
  • arr2;: 초기화되지 않은 상태로, 사용하려면 반드시 배열 객체를 생성하거나 참조를 할당해야 함.

 

for-each 문

Java에서 배열이나 컬렉션을 간단히 순회할 때 사용하는 반복문. 일반적인 for문보다 코드가 간결하고 가독성이 좋음.

 

특징

  1. 간결함:
    • 인덱스를 사용하지 않고, 순차적으로 배열 또는 컬렉션의 각 요소에 접근 가능.
  2. 읽기 전용:
    • 각 요소를 수정하려면 인덱스를 사용하는 for문을 사용해야 함.
  3. 안전성:
    • 인덱스를 관리하지 않아 인덱스 초과 예외(ArrayIndexOutOfBoundsException)가 발생할 가능성이 낮음.

단점

  1. 인덱스 접근 불가:
    • 특정 요소의 인덱스를 알아야 하거나, 요소를 수정해야 할 경우에는 사용할 수 없음.
  2. 순차 순회만 가능:
    • 순서를 제어하거나 역순으로 순회하려면 기존 for문을 사용해야 함.

언제 사용할까?

  • 배열이나 컬렉션의 모든 요소를 읽고 처리할 때 적합.
  • 요소를 수정하거나 인덱스를 활용해야 하는 경우는 일반적인 for문 사용.

java.util.Arrays api

ex) System.out.println(Arrays.toString(numbers));

 

자주 쓰는 메서드

메서드 설명
toString 배열을 문자열로 변환.
sort 배열을 정렬.
binarySearch 정렬된 배열에서 값 탐색.
copyOf 배열 복사 및 크기 변경.
equals 배열 비교.
fill 배열 요소를 특정 값으로 초기화.
stream 배열을 Stream으로 변환.
deepToString 다차원 배열을 보기 좋게 출력.
deepEquals 다차원 배열 비교.
asList 배열을 리스트로 변환.