Java에서 배열은 어떻게 쓸까요? C언어에서의 배열과 똑같습니다. 다만, 자바에서는 배열이 실제로 객체이기 때문에, Heap 영역에 생성이 된다는 것 정도의 차이밖에 없어요. 그리고 크기가 고정되어요. 즉, 고정 힙 배열, fixed heap array 정도로 생각하면 좋겠습니다.
예제 프로그램 1을 봅시다.
일단, 우리는, 크기가 2인 int형 배열 arr을 선언하려고 합니다. 그러면, int arr[] = new int[2]; 이렇게 선언할 수 있어요. int형을 저장할 수 있는 2개의 공간을 할당한다는 건데요. 일단 6번째 줄까지 수행이 되면, 메모리에 다음과 같이 저장이 됩니다.
arr이 int형을 2개 저장할 수 있는 공간을 가리키고 있어요. arr은 스택에, 실제로 real int를 2개 저장할 수 있는 공간은 힙에 할당이 될 거에요. 그리고 7번째 줄에 arr[0] = 1, arr[1] = 2 문장을 수행하는데요. 그것이 수행된 이후에는 다음과 같이 변할 겁니다.
그러면, 우리는 arr[0], arr[1]. 이런 식으로 접근할 수 있어요. 배열의 전체 원소를 순회를 어떻게 할 수 있을까요? 배열 객체에는 length라는 필드가 있습니다. 이것은 배열이 원소를 몇 개 가지고 있는지를 나타내는 것인데요.
arr.length의 값은 2입니다. 즉, 8번째 줄의 for문의 의미는 arr의 크기만큼 돌라는 겁니다. 9번째에서 arr[i]를 출력하라고 되어 있는데요. 보시면 arr[0]은 2, arr[1]이 3입니다. 따라서, 결과 값으로 2와 3이 출력됩니다. 어떠한 배열 객체의 원소 갯수는 length 필드로 접근할 수 있다는 점은 알아두시면 좋을 듯 싶네요.
그러면 n차원 배열도 선언할 수 있을까요? 네. 맞습니다. 이 중 저는 2차원 배열만 예로 들어보도록 하겠습니다.
저는 arr을 2by3으로 선언했습니다. int arr[][] = new int[2][3]; 이렇게 해도 되지만, 위 코드와 같이, 초기화 하셔도 무난합니다. 6번째 줄까지 수행되고 나서 메모리에는 어떻게 들어갈까요? 디버그를 해 보겠습니다.
보시면 arr[0]과 arr[1]에 id 값이 들어가 있는데요. 어떠한 객체를 가리킨다는 겁니다. 이것을 그림으로 그려보면, 아래와 같을 겁니다. arr[0]이 3개짜리 배열 객체를 가리키고, arr[1] 또한 3개짜리를 가리키고.
대충 이런 꼴입니다. 즉, arr[0]과 arr[1]은 객체를 가리키기 위한 값을 저장한다는 소리가 됩니다.
이제 예제 3을 봅시다.
이렇게도 선언할 수 있나요? 네. 각 행에 걸려있는 열의 갯수가 같지 않아요. 이를 우리는 톱니형 배열, Jagged array라고 부릅니다. Jag를 사전에서 찾아보면, 뾰족뾰족함, 들쭉 날쭉함이라는 뜻이 있는데, 여기에서는 들쭉 날쭉하다 정도가 조금 더 적당하지 않을까 싶어요. 어떠한 행에는 1개, 어떠한 행에는 5개 등등. 왔다 갔다 하니까요.
그러면, 메모리에 대충 이런 식으로 생성이 될 거에요. 그러면 이 요소들을 모두 출력하려면 어떻게 해야 할까요?
일단, arr의 length는 2입니다. 보라색으로 칠한 것이, arr이 가리키고 있는 녀석이기 때문입니다. 그러면, arr[0].length는 무엇일까요? arr[0]이 가리키고 있는 것을 따라가 봅시다.
초록색 부분을 가리키니까 1이겠군요. 따라서, 바깥쪽 for문에서 arr.length만큼 돌립니다. 안쪽 for문에서 arr[i].length만큼 돌리면 2차원 배열의 전체 원소를 탐색할 수 있을 겁니다. 이는 예제 3번 프로그램에서 7번, 9번째 줄에 대응됩니다.
문제는, 배열이 힙 고정입니다. 즉, 한 번 선언되면 크기를 바꿀 수 없어요. 그렇기 때문에, arr[][] = {{2}, {6,7,9,3,7}}; 이렇게 선언했을 때, arr[1]의 크기를 5가 아닌 6으로 만들 수 없어요. 6번째 줄이 끝나고 7번째 줄로 온 순간에 arr[1]의 크기는 5이기 때문입니다. size가 고정이 되는 셈입니다.
크기를 동적으로 늘리고 줄이기 위해서는 heap dynamic array를 써야 하는데요. 그냥 자료구조 시간에 언급한 동적 배열이라고 생각하시면 됩니다. Java에서는 ArrayList가 그러한 연산들을 지원합니다.
'코딩 > Java' 카테고리의 다른 글
java wrapper 클래스 : 기본 타입을 포장한다. (2) | 2019.08.29 |
---|---|
java 클래스 변수 : 어떻게 메모리에 올라갈까? (21) | 2019.08.22 |
java string intern 메서드 : pool이 된다는 것만 기억합시다. (2) | 2019.08.08 |
cp949 vs euc-kr : 어떤 차이점이 있는지 간단히 알아봅시다. (0) | 2019.08.04 |
java 참조 타입 vs 기본 타입 : 어떤 값을 저장하는가? (4) | 2019.08.03 |
최근댓글