Programming/Java

[ JAVA 수업 Day 04 ] 배열

빠모스 2020. 5. 4. 21:59
반응형

(배열의 기본적인 내용은 생략하고, 수업시간 내가 잘 알아둬야 할 내용을 필기한 위주로 정리했다.)

배열

  • 배열이란?

- 같은 종류의 데이터를 저장하기 위한 자료구조

- 크기가 고정되어 있다(한번 생성된 배열은 크기를 바꿀 수 없다)

- 배열을 객체로 취급

- 배열의 요소를 참조하려면 배열이름과 색인(index)라고 하는 int 유형의 정수값을 조합하여 사용한다.

 

왼쪽이 그냥 변수 세 개를 세웠을 경우, 오른쪽이 배열을 세웠을 경우

 

  • 참조변수 배열

참조변수 배열의 경우 stack에 변수이름으로 된 공간이 생기고 Heap에 그 크기 개수만큼의 공간이 생긴다.

각 공간에 문자열을 할당하면 그 공간이 각각의 문자열을 저장한 heap 공간의 주소를 가리키게 된다.

 

  

급하게 그리느라 별로지만 대충 이런 느낌.

   

 

Strring[] strArr; //  => stack에 공간 생성
strArr = new String[3]; // => heap에 3개만큼의 공간 생성
strArr[0] = “poly”; // => heap에 “poly”가 저장된 공간을 생성하고 각각 참조하게 한다.
strArr[1] = “java”;
strArr[2] = “edu”;

 

 

=> 이 구조를 잘 기억해야 나중에 nullpointexception을 피해갈 수 있다.

 

 

  • 인덱스에 변수를 넣을수도 있다.
strArr[loc++] = “폴리텍”;
strArr[loc++] = “광명”;
strArr[loc++] = “자바”;

=> 이렇게 하면 중간에 무언갈 새로 추가할때 그냥 넣으면 되서 편함. 

 

 

array API

String[] strArr = {“poly”, “java”, “edu”};
String[] copyArr = strArr; // => strArr값을 그대로 복사하고싶은 배열

=> 이렇게 복사하면 복사는 되지만, strArr 값이 바뀔때 copyArr도 같이 바뀌지 않음. String은 참조변수이기때문에.

 

strArr[1] = “hello world”; // 1번 인덱스 string을 바꿔본다.

그 후 strArr과 copyArr를 출력하면 strArr의 1번째만 hello world가 반영되었다.

 

그런데 참조변수가 아니라 int[] 배열은 copyArr도 값이 바뀌더라.

int[] arr = {10, 20, 30, 40, 50};
int[] copyArr = arr;
arr[2] = 100;
// => copyArr[2]값도 100으로 바뀐다.

 

 

shallow copy  

 

 

=> 위처럼 copyArr에 단순히 arr을 할당해주면 heap 영역 하나의 공간을 두개의 참조변수가 참조하게 된다. 이를 shallow copy라고 한다.

 

 

Deep copy       

 

 

deep copy는 copyArr도 개별의 공간에 같은 값을 복사하는 것이다.

 

이렇게 하려면 arr의 각 인덱스값을 copyArr에 하나씩 할당해주는 방법이 있다. 

copyArr = new int[arr.length];

for(int i = 0; i < arr.length; i++) {
	copyArr[i] = arr[i];
}

 

하지만, 매번 이렇게 해주려면 귀찮다. 그래서 있는 메소드가 바로 System.arraycopy

 

System.arraycopy(arr, 0, copyArr, 0, arr.length);
// => arr의 0번지부터 copyArr의 0번지에 arr.length만큼 복사한다.

System.arraycopy(arr, 2, copyArr, 0, 3);
// => 이렇게 응용도 가능하다. Arr의 3번 인덱스부터 copyArr의 0번지에 3개만 복사한다.

// 복잡한 방법으로는
for(int i = 2, j = 0; i < arr.length; i++, j++) {
	copyArr[i] = arr[i];
}

cf) 단순 배열값 확인을 위해선 반복문을 통해 모든 요소를 돌 필요 없이, Arrays.toString API로 가능하다.

System.out.println(Arrays.toString(destArr);

 

 

초기화

int[] ar = {10, 20, 30, 40, 50}; // 처음 배열 세우고 값 할당할땐 new int[]를 생략해도 됨.
ar = {500, 400, 300}; // => 불가능. 
// But, 이미 선언된 배열을 고칠때는 반드시 new int를 명시해야 한다.
ar = new int[]{500, 400, 300};

이 때 이전의 배열 {10, 20, 30, 40, 50}은 메모리에 남아있게되고, ar은 새로운 수들이 저장된 heap영역의 주소를 참조하게 된다. 후에 garbage collector가 지운다.

 

2차원 배열

int[][] arr = new int[3][2]; // 만약 이렇게 2차원 배열을 생성했다면

 

arr : // 이는 곧 세 개의 1차원 int 배열이 생성된것이고, 각 배열은 int형 자료를 갖는다.

int [][]   ->   int[]   -> int int

              ->   int[]   -> int int

              ->   int[]   -> int int

 

But, int[][] arr2 = new int[3][]; 처럼, 두번째 인덱스는 생략 가능 (동적할당).

 

arr2 -> null ->  후에 할당

            null

            null

 

arr2[0] = new int[4];

arr2[1] = new int[2]; // 길이가 다르게 할당할 수 있다.

 

실습 코드

(to be updated...)

 

반응형