SHUSTORY

07-1 배열 본문

프로그래밍/JAVA

07-1 배열

어서오시우 2023. 2. 24. 16:37
728x90

자료를 순차적으로 관리하는 구조, 배열

배열을 사용하면 자료형이 같은 자료 여러 개를 한 번에 관리할 수 있다.

 

배열 선언

배열 선언 문법

배열을 사용하려면 이전에 배웠던 변수와 마찬가지로 먼저 선언해야 한다.

배열을 이루는 각각의 자료를 배열 요소라고 한다. 배열 요소는 자료형이 모두 같다.

먼저 저장하려는 자료의 성격에 맞게 자료형을 정하고 선언하려는 배열 요소 개수만큼 [ ] 안에 적는다.

배열 선언 예제

위 예제를 통해 살펴보자면 int형 요소가 10개인 배열을 선언한 것으로

배열 길이는 10개, 배열 전체 바이트는 40바이트이다.

 

배열 초기화

자바에서 배열을 선언하면 그와 동시에 각 요소의 값이 초기화된다.

배열의 자료형에 따라 정수는 0, 실수는 0.0, 객체 배열은 null로 초기화되며,

배열 선언과 동시에 특정 값으로 초기화도 가능한데, 이 경우 초기화 요소 개수만큼 초기화되므로 [ ]의 개수는 생략한다.

배열 선언과 동시에 초기화

만약 [ ] 내부에 개수를 적는다면 오류가 발생한다.

또한 배열 선언과 동시에 초기화 할 때에는 new int[ ] 부분은 생략 가능하다.

new 자료형[ ] 생략

하지만 배열의 자료형을 먼저 선언한 뒤 따로 초기화하는 경우는 new 자료형[ ]부분을 생략할 수 없다.

배열 선언 / 초기화

 

배열 사용하기

선언한 배열의 각 요소에 값을 넣을 때나 배열 요소에 있는 값을 가져올 때는 [ ]를 사용한다.

[ ] 인덱스 연산자는 배열을 처음 선언할 때 사용한 연산자이다.

배열에서 [i] 인덱스 연산을 사용하면 i번째 요소의 위치를 찾아 해당 위치의 메모리 값을 넣거나

값을 가져와서 사용할 수 있다.

참고로 인덱스 요소는 0부터 시작하기 때문에, 배열 길이가 n일 경우 배열의 순서는 0부터 n-1이다.

 

* 배열 이외에 다른 자료 구조를 살펴보면 종종 물리적 위치와 논리적 위치가 다른 경우가 있는데,

  배열의 물리적 위치와 논리적 위치는 같다.

 

예제01

 

참고로 예제01과 같이 println으로 작성하면 출력값이 한 줄씩 출력되지만

예제02와 같이 print로 작성하면 출력값이 한 행에 출력된다.

 

예제02

 

length

자바의 배열은 배열 길이를 나타내는 length 속성을 가진다.

배열 길이는 처음에 선언한 배열의 전체 요소 개수를 의미하며, 배열 이름.length 와 같이 작성하여 배열 길이를 반환한다.

* 배열 전체 길이만큼 수행문을 반복해야 할 경우 숫자를 작성하는 것 보다 length 속성을 사용하도록 하자.

 

전체 배열 길이와 유효한 요소 값

선언한 배열 길이만큼 값을 저장해서 사용하는 경우는 많지 않기 때문에,

전체 배열 길이와 현재 배열에 유효한 값이 저장되어 있는 배열 요소 개수가 같다고 혼동하면 안 된다.

 

예제03

예제03을 통해 살펴보면 별도로 초기화하지 않고 선언한 배열의 요소 값은 0으로 초기화된다.

즉 세 번째 요소까지만 유효한 값이 저장된 것이다.

만약 유효한 값만을 출력하려면 새로운 변수를 선언하고 배열 요소 순서대로 값을 저장할 때마다 그 변수 값을 증가시킨다.

 

예제04

 

예제04와 같이 작성해 배열 길이만큼 for문을 반복하는 것이 아닌 유효한 개수만큼 반복하도록 할 수 있다.

 

문자 저장 배열 만들기

문자 자료형 배열은 char[ ]로 선언한다.

 

예제05

 

8행 for문 내부를 보면 ch++를 볼 수 있는데, 각 알파벳 문자는 실제 메모리에 아스키 코드 값으로 저장되기 때문에

ch 값에 1을 더하면 1만큼 증가한 값이 배열에 저장되는 것이다.

14행에서는 형 변환 연산자 (int)를 사용해 배열에 저장된 char형 문자를 int형 정수로 변환해 출력할 수 있도록 한다.

 

객체 배열 사용하기

객체 배열은 참조 자료형으로 선언한다.

참조 자료형 변수도 여러 개를 배열로 사용할 수 있다.

 

예제06

 

Book 클래스는 책 이름과 저자를 멤버 변수로 갖는다.

디폴트 생성자와 책 이름, 저자 이름을 매개변수로 받는 생성자를 하나 더 구현했다.

다른 코드에서 이 클래스를 사용할 때 멤버 변수 값을 가져오거나 지정할 수 있도록 set( ), get( ) 메서드를 구현하고,

책의 정보를 구현하는 showBookInfo( ) 메서드를 구현했다.

 

예제07

 

6행에서 코드의 내용을 보면 Book 인스턴스가 5개 생성된 것처럼 보이지만 그것은 아니다.

인스턴스를 생성하면 인스턴스를 가리키는 주소 값이 있는데,

6행에서는 각각의 인스턴스 주소 값을 담을 공간 5개가 생성된 것이다.

그렇기 때문에 출력했을 때 이 주소 값을 담을 공간 5개가 '비어있다'는 의미로 null 값이 출력되는 것이다.

 

예제08

 

배열의 각 요소에 Book 인스턴스를 만들어 직접 저장했다.

출력 결과를 통해 인스턴스가 모두 잘 생성되었고, 인스턴스를 저장한 메모리 공간 주소를 확인할 수 있다.

 

배열 복사하기

기존 배열과 자료형 및 배열 크기가 똑같은 배열을 새로 만들거나

배열의 모든 요소에 자료가 꽉 차서 더 큰 배열을 만들어 기존 배열에 저장된 자료를 가져오려 할 때 배열을 복사한다.

 

배열을 복사하는 방법으로는 다음 두 가지가 있다.

  • 기존 배열과 배열 길이가 같거나 더 긴 배열을 만들고 for문을 사용하여 각 요소 값을 반복해서 복사하는 방법
  • System.arraycopy( ) 메서드를 사용하는 방법

다음은 System.arraycopy(src, srcPos, dest, destPos, length) 메서드의 매개변수 의미이다.

매개변수 설명
src 복사할 배열 이름
srcPos 복사할 배열의 첫 번째 위치
dest 복사해서 붙여 넣을 대상 배열 이름
destPos 복사해서 대상 배열에 붙여 넣기를 시작할 첫 번째 위치
length src에서 dest로 자료를 복사할 요소 개수

 

예제09

 

예제09에서는 요소를 4개만 복사했기 때문에 마지막 행의 출력값이 기존의 array2 배열의 마지막 값인 5이다.

만약 요소 6개를 복사한다고 코드를 수정하면 array1과 array2 배열 길이보다 요소 개수가 많아지므로 오류가 발생한다.

 

객체 배열 복사하기

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

예제10

 

예제10에서 bookArray1 배열의 요소를 bookArray2 배열에 정상적으로 복사해 출력해보았다.

그런데 bookArray2 배열의 인스턴스를 따로 만들지 않았는데 어떻게 요소 값이 잘 출력되는 것일까?

객체 배열을 상요하려면 꼭 인스턴스를 생성해서 넣어야 한다.

이는 객체 배열의 요소에 저장된 값이 인스턴스 자체가 아닌 인스턴스 주소 값으로,

bookArray1 배열의 인스턴스 주소 값을 bookArray2 배열에 복사했기 때문이다.

즉 bookArray1[i]와 bookArray2[i]는 모두 같은 주소 값을 가리킨다. (예제11 참고)

 

예제11

 

위에서 설명한 것은 얕은 복사와 관련이 있다.

얕은 복사와 깊은 복사에 대해 알아보자.

 

얕은 복사

예제12

 

예제12를 보면 bookArray1의 변경 사항이 bookArray2에도 적용된 것을 확인할 수 있다.

이는 객체 배열의 요소에 저장된 값은 인스턴스 자체가 아니고 인스턴스의 주소 값이기 때문이다.

따라서 객체 배열을 복사할 때 인스턴스를 따로 생성하는 게 아니라 기존 인스턴스의 주소 값만 복사한다.

결국 두 배열의 서로 다른 요소가 같은 인스턴스를 가리키고 있으므로 복사되는 배열의 인스턴스 값이 변경되면

두 배열 모두 영향을 받는 것이다.

 

깊은 복사

그렇다면 인스턴스 값만 복사하고, 두 배열의 각 요소가 다른 인스턴스를 가리키게 하려면 어떻게 해야 할까?

이는 깊은 복사를 통해 이루어진다.

반복문을 사용하건 System.arraycopy( ) 메서드를 사용하건 객체 배열을 복사하면 항상 인스턴스 주소 값이 복사된다.

인스턴스를 따로 관리하고 싶다면 직접 인스턴스를 만들고 그 값을 복사하는 '깊은 복사'를 수행하도록 한다.

 

배열에 인스턴스를 따로 생성한 후 요소 값을 복사하면 복사한 배열 요소는 기존 배열 요소와 서로 다른 인스턴스를 가리키므로 기존 배열의 요소 값이 변경되어도 영향을 받지 않는다.

예제13

 

향상된 for문과 배열

향상된 for문

자바 5부터 제공되는 향상된 for문은 배열의 처음에서 끝까지 모든 요소를 참조할 때 사용한다.

향상된 for문은 배열 요소 값을 순서대로 하나씩 가져와서 변수에 대입한다.

따로 초기화와 종료 조건이 없기 때문에 모든 배열의 시작 요소부터 끝 요소까지 실행한다.

예제14

 

예제14를 통해 lang 변수에 배열의 각 요소가 대입된 것을 확인할 수 있다.

'프로그래밍 > JAVA' 카테고리의 다른 글

07-3 ArrayList 클래스 사용하기  (0) 2023.02.25
07-2 다차원 배열  (0) 2023.02.25
06-4 변수 유효 범위  (0) 2023.02.23
06-3 static 변수  (0) 2023.02.23
06-2 객체 간 협력  (1) 2023.02.23