학원 수업

19일차 - java '배열'

Hiolet 2021. 11. 5. 00:17

배열

배열은 같은 자료형 변수 여러개를 한 번에 관리할 수 있다.

배열을 이루는 각 자료를 배열 요소라고 한다.

 

배열 선언과 초기화

 

자료형[ ] 배열이름 = new 자료형[개수];
자료형 배열이름[ ] = new 자료형[개수];

 

위, 아래 어느 방식으로 써도 된다.  

기본 형태가 new라는 건 참조자료형이라는 말이다.

나는 자료형[ ] 배열이름 = new 자료형[개수];으로 코드를 짰다.
배열을 초기화 할 때는 조금 유의해야하는데 생략하는 부분과 아닌 부분을 잘 구분해야 되기 때문이다.
배열 선언과 동시에 초기화를 하게 되면 개수는 생략한다.

 

int[ ] studentIDs = new int[ ] {101,102,103,104,105};
여기서 배열 개수를 쓴다면 오히려 오류가 난다.

 

 

new 자료형[ ] 부분은 생략해도 된다.

 

 


 

length

 

 

배열의 길이를 나타내는 속성으로 length를 쓴다. 배열 변수 안에 멤버변수로 들어가 있다.

배열  전체 길이는 배열의 전체 요소 개수를 의미한다. 
for문에서 배열을 배열의 개수만큼 반복해야 할 때 도트(.)연산자를 쓰고 length를 쓴다.

*도트연산자로 나오는 것은 모두 객체 변수

 

 

반복문 안에 있는 변수 i는 배열의 요소로 0부터 시작한다. 

그리고 .length는 말 그대로 개수이기 때문에 1부터 시작한다.

항상 배열 요소 값과 개수는 -1 차이가 나기 때문에 반복문이 돌면서 마지막 요소를 처리하고

한 번 더 1증가하면 배열의 개수와 값이 같아진다. 그 때를 < 부등호를 써서 false로 만들고 반복문을 끝낸다.

 


 

참조자료형을 배열로 만들기

 

 

클래스형으로 선언하는 변수(참조자료형 변수)도 여러 개를 배열로 사용할 수 있다. 

기본 자료형 배열과 비슷하지만 조금 다르다.

 

 

기본 자료형 배열에서 배열에 있는 값을 가져올 때는 아래처럼 코드를 작성하면 됐다.

 

 

배열에서 [ ] (인덱스 연산)으로 배열의 요소에 값을 넣거나 이미 저장되어 있는 값을 가져와서 쓸 수 있다.

 

 

하지만 객체 배열은 배열을 담을 수 있는 위치만 만들어지고 객체마다 인스턴스를 생성해줘야 한다.

 

 

 

Book 클래스형으로 객체 배열을 생성했다.

 

 

 

그 다음 각 배열 요소에 인스턴스를 생성했다.

그렇다면 값을 넣기 위해 매개변수가 있는 생성자가 필수겠지?

 

객체 배열이 인스턴스를 생성하는 코드는 인스턴스 값을 담을 공간을 만든다는 것을 뜻한다.

따라서 각각 인스턴스를 만들어 만들어진 공간에 값을 저장해줘야 제대로 인스턴스가 생성된다.

 


 

배열 복사

 

 

System.arraycopy() 메서드로 배열을 복사(얕은 복사)할 수 있다.

 

 

src : ctrl + c 할 대상

srcPos : ctrl + c 할 때 커서

dest : ctrl + v 할 대상

destPos : ctrl + v 할 때 커서 

length :  복사 할 개수 

 

 

 

출력 결과를 보면 array2의 두번 째 요소부터 array1의 첫 번째 요소부터 네번째 요소까지 4개가 복사되었다.

 

 

객체 배열도 복사할 수 있다.

 

 

 

Book 클래스를 만들고 인스턴스를 생성했다.

그리고 library1에만 요소 값을 주고 library2로 복사했다.

그리고 library2를 출력봤더니 library1에서 복사된 값이 출력되었다.

 

그런데 객체 배열은 각각 인스턴스를 만들어서 값을 저장해야 한다.

이렇게 복사만 했다고 인스턴스가 만들어진게 아니라는 소리.  인생 그렇게 호락호락하지 않지 

확인하기 위해 library1의 첫번째 요소 값을 바꾸는 코드를 추가해서 배열 각각을 출력했다.

 

 

 

library1를 library2로 복사한 뒤 요소 값을 바꾸고 library2를 출력해도 변경 사항이 반영되어 출력된다.

왜냐하면 객체 배열의 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스 주소 값이기 때문이다. 따라서 객체

이게 무슨 말이야 0개 국어 인증 

 

책에 나온 이야기는 뭐라는지 이해가 잘 안 되서 읽어보고 내 나름대로 생각해봤는데,

System.arraycopy() 메서드는 거울이라고 생각하면 된다.

인스턴스 없어서 거울처럼 복사된 대상을 반사만 하기 때문에  줏대 없이  수정된 코드에도 영향을 받는다. 

 

 

그런데 이렇게 ctrl + c 할 대상의 변경사항에 영향을 받지 않고 싶다면 다른 방식(깊은 복사)으로 배열 복사를 해야 한다.

이 때는 이제 ctrl + v 할 대상의 인스턴스를 생성해서 for문으로 복사를 하면 된다.

 

 

얕은 복사 방식이 거울이라면

이렇게 인스턴스 생성하고 for문으로 하는 복사(깊은 복사)하는 방식은 사진이라고 이해하면 되겠다.

인스턴스를 생성하고 배열에 저장하기 때문에 수정된 코드에도 영향을 받지 않는다.  내 마음에 저장 

 

 


 

향상된 for문

 

 

배열의 모든 요소를 참조할 때 사용한다.

 

 

 

향상된 for문으로 배열의 요소값을 출력하는 코드가 for문 보다 훨씬 간결하다.