본문 바로가기

Study/Java

[Java]배열

먼저 JVM(자바 가상 머신)에는 method(메서드) 영역, heap(힙) 영역, stack(스택) 영역이 있다. method 영역에는 클래스에 대한 정보가, heap 영역에는 참조 데이터 타입의 데이터가, stack 영역은 메서드 호출 시 관계되는 변수가 저장된다. 이 stack 영역에서는 메서드가 호출될 때 메모리 공간을 제공했다가 메서드가 종료되면 회수한다. 그리고 배열(Array)은 참조 타입이기 때문에 heap 영역 메모리로 저장된다.

 

배열

java에서 배열은 데이터 타입이 상관없는 JS와 달리, 동일한 데이터 타입 변수들의 집합체다. 메모리 상에서 연속된 공간에 생성되며, 생성 후에는 배열 크기를 바꿀 수 없다. 인덱스 번호는 똑같이 0에서 시작하지만, JS와 다르게 없는 인덱스 호출 시에는 에러가 난다. 만약 배열을 생성하고 초기화를 하지 않으면 기본값(0, 0.0, false, null)으로 자동 초기화된다.

배열 선언은 데이터타입[] 변수명 = new 데이터타입[배열크기]; 로 생성된 배열의 주소 값과 heap 메모리 주소 값을 변수에 저장한다. 초기화하려면 변수명[인덱스] = 데이터; 라고 쓰면 되는데, 선언과 초기화를 데이터타입[] 변수명 = {데이터}; 로 동시에 할 수 있다. 배열 역시 새로 초기화가 가능하지만, 원래 배열 제거 후 새로 생성하는 방식으로 이뤄진다. 재 초기화는 변수명 = new 데이터타입[] {데이터}; 로 한다.

아래는 여러 학생의 점수의 총합과 평균을 내는 배열 코드다. 여기서 배열명.length 는 배열의 길이를 말한다. 인덱스 0번이 길이 1이기 때문에 인덱스를 따질 때는 배열명.length -1 을 해야 한다.

int sum = 0;
double average = 0;    //평균은 정수로 나눠지지 않는 실수

int[] score = {100, 87, 70};
String[] name = {"홍길동", "이순신", "강감찬"};

for(int i=0; i<name.length; i++) {
	System.out.println(name[i] + ", " + score[i] + "점");    //두 배열 길이가 같아야 함
	sum += score[i];
}
average = (double)sum/score.length;    //sum을 나누기 전에 먼저 형 변환

System.out.println(sum);
System.out.println(average);

 

추가로 아래 코드는 배열 내의 정수 중 가장 큰 값을 찾아내는 코드다. 값을 하나씩 비교하는 방법으로 작성했다.

int[] num = {9,2,15,32,100,21,70,48,7};
int max = num[0];

for(int i=1; i<num.length; i++) {
	if(max < num[i]) {
		max = num[i];    //더 큰 값을 계속 max에 대입
	}
}
System.out.println(max);

 

다차원 배열

기본 배열을 2개 겹쳐서 행열을 가진 2차원 배열로 만들 수도 있다. 2차원 배열 선언은 데이터타입[][] 변수명 = new 데이터타입[행크기][열크기]; 로 할 수 있고, 접근은 변수명[행 인덱스][열 인덱스] 로 한다. 초기화는 한 칸 한 칸 하기 오래 걸리기 때문에, 선언과 한꺼번에 데이터타입[][] 변수명 = { {행1데이터 ...}, {행n데이터 ...} }; 식으로 하면 된다. 2차원 배열 역시 재 초기화 시 원래 배열은 삭제된다.

2차원 배열에서 배열명.length 는 행 크기를 뜻하고, 열 크기를 확인하려면 배열명[행 인덱스].length 로 해야 한다. 아래는 2차원 배열의 모든 데이터를 출력하는 다중 for문 코드다. 바깥쪽 for문에 행 정보를, 안쪽 for문에 열 정보를 적는 방식이다.

int[][] arr = {    //2차원 배열 선언, 초기화
	{10,20,30},
	{40,50,60},
	{70,80,90}
};

for(int i=0; i<arr.length; i++) {    //3행
	for(int j=0; j<arr[i].length; j++) {    //3열
		System.out.println(arr[i][j]);    //arr[0][0]부터 arr[2][2]까지 순서대로 출력
	}
}

 

가변 배열

가변 배열이란 열의 길이를 명시하지 않고, 행마다 다른 길이로 저장하는 다차원 배열이다. 배열 생성은 데이터타입[][] 변수명 = new 데이터타입[행크키][]; 로 하고, 열은 지정하지 않는다. 열은 변수명[행 인덱스] = new 데이터타입[열크기]; 로 각 행마다 따로 생성한다. 하지만 배열 생성 시 모두 초기화를 할 수도 있는데, 2차원 배열과 똑같은 방법으로 각 행 데이터 개수만 다르게 하면 된다.

아래는 중첩 for문을 이용한 5행 파스칼의 삼각형 코드다. 파스칼의 삼각형은 계단 형식으로, 각 행 0번과 맨 끝 열은 1을 입력, 나머지는 (같은 열 -1행 데이터) + (-1행 -1열 데이터) 의 값을 입력하는 방식이다. 그래서 행이 내려갈수록 열 길이도 하나씩 늘어나야 하기 때문에 가변 배열을 사용한다.

int[][] pas = new int[5][];

for(int i=0; i<pas.length; i++) {
	pas[i] = new int[i+1];

	for(int j=0; j<pas[i].length; j++) {
		if(j==0 || j==i) {
			pas[i][j] = 1;
		}
		else {
			pas[i][j] = pas[i-1][j-1] + pas[i-1][j];
		}
		System.out.print(pas[i][j] + " ");
	}
	System.out.println();
}

 

향상된(inhanced) for문

배열 등의 객체에 사용하기 위해 for문을 좀 더 편한 방법으로 만든 것이 inhanced for문이다. for-each문이라고도 부르며, 조건식과 증감식이 없고 배열 내의 모든 데이터 실행 후 자동으로 종료된다. for(데이터타입 변수명 : 배열명) { 실행문; } 형식으로 적는다. 다차원 배열의 경우에는 아래와 같이 inhanced for문을 중첩하여 사용한다.

int[][] a = {
	{80,80,90},
	{90,70,60},
	{100,50,100}
};

for(int[] arr : a) {    //각 행을 의미하는 변수 arr
	for(int num : arr) {    //각 데이터를 의미하는 변수 num
		System.out.println(num);
	}
}

'Study > Java' 카테고리의 다른 글

[Java]생성자와 패키지, 접근제한자  (0) 2022.01.26
[Java]OOP - 클래스와 메서드  (0) 2022.01.23
[Java]연산자와 제어문  (0) 2022.01.11
[Java]자료형과 변수, 형 변환  (0) 2022.01.04
자바(Java)  (0) 2022.01.02