[Java] 배열

박은지·2022년 2월 26일
0

메모리 구조

모든 자바 프로그램은 자바 가상 머신(JVM)을 통해서 실행된다.
자바 프로그램이 실행되면, JVM은 운영 체제로부터 해당 프로그램을 수행할 수 있도록 필요한 메모리를 할당받는다.

이렇게 할당받은 메모리를 JNM은 용도에 따라 다음과 같이 구분하여 관리한다.

메소드( Method ) 영역

메소드(method) 영역은 자바 프로그램에서 사용되는 클래스에 대한 정보클래스 변수(static variable)가 저장되는 영역이다.
JVM은 자바 프로그램에서 특정 클래스가 사용되면 해당 클래스의 클래스 파일(.class)를 읽어들여, 해당 클래스에 대한 정보를 메소드 영역에 저장한다.

힙( Heap ) 영역

힙(heap) 영역은 자바 프로그램에서 사용되는 모든 인스턴스 변수가 저장되는 영역이다.
JVM은 자바 프로그램에서 new 키워드를 사용하여 인스턴스가 생성되면, 해당 인스턴스의 정보를 힙 영역에 저장한다.
힙 영역은 메모리의 낮은 주소에서 높은 주소의 방향으로 할당된다.

스택( Stack ) 영역

스택(stack) 영역은 자바 프로그램에서 메소드가 호출될 때 메소드의 스택 프레임(stack frame)이 저장되는 영역이다.
JVM은 자바 프로그램에서 메소드가 호출되면, 메소드의 호출과 관계되는 지역 변수와 매개변수를 스택 영역에 저장한다.
스택 영역은 메소드의 호출과 함께 할당되며, 메소드의 호출이 완료되면 소멸된다.
이렇게 스택 영역에 저장되는 메소드의 호출 정보를 스택 프레임(stack frame)이라고 합니다.

스택 영역은 푸시(push) 동작으로 데이터를 저장하고, 팝(pop) 동작으로 데이터를 인출한다.
이러한 스택은 후입선출(LIFO, Last-In First-Out) 방식에 따라 동작하고, 메모리의 높은 주소에서 낮은 주소의 방향으로 할당된다.


배열 ( Array )

배열(Array)란 같은 타입의 변수들로 이루어진 유한 집합이라고 정의할 수 있다.
배열을 구성하는 각각의 값들을 배열 요소(Element)라 하고, 배열에서의 위치를 가리키는 숫자를 인덱스(Index)라고 한다.
Java에서의 인덱스는 항상 0부터 시작하며, 0을 포함한 양의 정수만을 가질 수 있다.

1차원 배열

배열의 선언과 생성을 "따로"

배열 선언

배열은 다음 2가지 방법으로 선언할 수 있다.

문법

  • 타입[ ] 배열이름 ;
  • 타입 배열이름 [ ] ;

💡 배열을 만들기 위해 위의 두 가지 방법을 모두 사용할 수 있지만, 첫 번째 방법을 권장한다.

배열 생성

위와 같이 선언된 배열은 new 키워드를 통해 실제 배열을 생성한다.

문법
배열이름 = new 타입 [ 배열길이 ] ;

배열의 선언과 생성을 "동시에"

다음은 배열의 선언과 생성을 동시에 하는 방법이다.

문법
타입[ ] 배열이름 = new 타입 [ 배열길이 ] ;

배열의 초기화

문법
배열이름[ 인덱스 ] = 해당_인덱스에_넣을_값 ;

Java에서는 이러한 배열도 모두 객체이고, 각각의 배열은 모두 자신만의 필드와 메소드를 가지고 있다.

// 배열 선언 & 생성
int[] array1 = new int[3];

// 배열 초기화
array1[0] = 11;
array1[1] = 22;
array1[2] = 33;

배열의 선언과 초기화를 "동시에"

배열의 선언과 동시에 초기화할 수 있다.

문법

  • 타입[ ] 배열이름 = [ `배열요소1, 배열요소2 . . . ] ;
  • 타입[ ] 배열이름 = new 타입 [ 배열요소1, 배열요소2 . . . ] ;

다차원 배열 (Multi-dimensional Array)

다차원 배열은 2차원 이상의 배열을 의미하며, 배열 요소로 또 다른 배열을 가지는 배열을 의미한다.

2차원 배열 (Two dimensional Array)


2차원 배열이란 배열의 요소로 1차원 배열을 가지는 배열이다.
자바에는 2차원 배열을 나타내는 타입이 따로 존재하지 않기 때문에 1차원 배열의 배열 요소로 또 다른 1차원 배열을 사용하여 2차원 배열을 나타낼 수 있다.

배열의 선언

2차원 배열의 선언은 다음과 같이 3가지 방법으로 한다.

문법

  • 타입[ ][ ] 배열이름 ;
  • 타입 배열이름 [ ][ ] ;
  • 타입[ ] 배열이름 [ ] ;

선언과 초기화를 동시에

1차원 배열과 마찬가지로 2차원 배열도 선언과 동시에 초기화할 수 있다.

문법
타입 배열이름[ 열의길이 ][ ```행의길이``` ] = {
{ 배열요소[0][0] , 배열요소[0][1] , ... } ,
{ 배열요소[1][0] , 배열요소[1][1] , ... } ,
. . .
};

가변 배열 ( Dynamic Array )

Java에는 2차원 배열 생성 시, 열의 길이를 명시하지 않음으로써, 행마다 다른 길이의 배열을 요소로 저장할 수 있다.
이렇게 행마다 다른 길이의 배열을 저장할 수 있는 배열을 가변 배열(Dynamin Array)이라고 한다.

아래의 예시 코드처럼 배열 생성 시, 두 번째 첨자를 생략하면 가변 배열을 만들 수 있다.

int[][] arr = new int[3][];

arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];

또한, 가변 배열도 초기화 블록을 사용하여 배열의 선언과 초기화를 동시에 수행할 수 있다.

int[][] arr = {
	{ 10, 20 },
    { 30, 9, 33 },
    { 24 }
}

배열의 활용

배열의 복사

Java에서 한 번 생성된 배열은 그 길이를 변경할 수 없다.
따라서 배열 안에 더 많은 데이터를 저장하려면 더 큰 배열을 만든 후, 이전 배열의 데이터를 새로 만든 배열로 복사하는 작업을 수행해야 한다.

배열의 복사는 다음과 같은 방법으로 수행할 수 있다.

  • System 클래스의 arraycopy( ) 메소드
  • Array 클래스의 copyOf( ) 메소드
  • Object 클래스의 clone() 메소드
  • for문인덱스를 이용한 복사

Enhanced for 문

JDK 1.5부터 배열과 컬렉션의 모든 요소를 참조하기 위한 Enhanced for문이라는 반복문이 새롭게 추가되었다.

문법
for ( 타입 변수이름 : 배열이나_컬렉션_이름 {
배열의_길이만큼_반복적으로_실행하고자_하는_명령문 ;
)

Enhanced for문은 명시한 배열 혹은 컬렉션의 길이만큼 반복되어 실행된다.
루프마다 각 요소는 명시한 변수의 이름으로 저장되고, 명령문에서는 이 변수를 사용하여 각 요소를 참조할 수 있다.

다음은 Enhance for 문을 사용해서 배열 안에 존재하는 각 요소들을 출력하는 코드이다.

int[] arr = new int[]{1, 2, 3, 4, 5};

for (int e : arr) {
	System.out.print(e + " ");
}

// 실행결과
// 1 2 3 4 5

💡 여기서 주의할 점! Enhanced for문은 요소를 참조할 때만 사용하는 것이 좋으며, 요소의 값을 변경하는 값에는 적합하지 않다.
그 이유는 Enhanced for문 내부에서 사용되는 배열 요소는 복사본일 뿐, 배열 요소 그 자체가 아니기 때문이다.
따라서 Enhance for 문에서 배열 요소의 값을 변경하여도 원본 배열에는 아무런 영향을 주지 못한다는 것을 기억하자!

0개의 댓글