상세 컨텐츠

본문 제목

JAVA 7-1. 참조타입 : 배열타입

Backend/JAVA-자바

by 사랑짱 2021. 6. 6. 14:45

본문

 

◆ 배열이란?

- 같은 타입의 데이터를 연속된 메모리 공간에 저장하는 자료구조

- 각 데이터 저장 위치는 index를 부여하여 접근

자료구조(Data Structure)란?
여러 데이터(변수)를 효율적으로 저장, 조작할지 고민해서 만든 프레임

 

 

◆ 배열의 특징

- 같은 타입의 데이터만 저장할 수 있다.

- 한 번 생성된 배열은 길이를 늘리거나 줄일 수 없다.

 

 

◆ 배열의 사용

배열 사용의 장점은 중복된 변수 선언을 줄일 수 있으며,

반복문을 이용하여 요소들을 쉽게 처리할 수 있다는 것이다.

그렇다면 배열의 사용은 어떻게 하는 것일까?

 

Step 1. 배열 선언

- 저장하는 자료의 타입에 맞게 자료형을 정하고 배열 변수를 선언한다. 

- 배열 변수는 참조 변수이기 때문에 배열이 생성되기 전 null로 초기화가 가능하다.

   ( "타입[  ] 변수 = null;" ----> 이런 경우, 인덱스에는 접근할 수 없다. )

타입[  ] 변수;  <--- 자바에서 권장!
타입 변수[  ]; 

Step 2. 배열 객체 생성 및 초기화

① 값 목록으로 배열 생성 : ex. 타입[ ] 변수 = { 값1, 값2, 값3, ....} 

- 배열 변수를 선언과 동시에 값 목록을 대입하여 값을 초기화하고 생성한다.

 

② new 연산자로 배열 생성 : ex. 타입[ ] 변수 = new 타입[길이];

- new 연산자로 배열을 생성하면 값 목록을 가지고 있지 않아

  각 요소의 값이 초기화되어 생성된다. (정수는 0, 실수는 0.0, 객체 배열은 null로 초기화)

- 배열의 타입과 요소의 수를 알고 있으며, 배열을 메모리에 미리 생성하고 싶을 때 사용한다.

 

※ 배열 변수의 선언과 배열객체 생성 및 초기화가 두 개의 실행문장으로

분리되면 반드시 new 연산자로 배열 객체를 생성해야 한다.

(ex. 메소드의 매개변수로 배열 변수가 선언되어 있을 때도 new 연산자로 생성해야 하는 이유가 바로 이것!)


Step 3. 배열 사용

 

※ 전체 배열 길이와 유효한 요소의 값은 항상 같지 않으며, 저장한 요소의 개수만큼 유효하다.

※ 객체 배열은 배열에 인스턴스 주소값을 담고 있으므로 값을 호출하는 메소드를 생성해야 한다.

 배열을 포함한 자료구조의 모든 요소의 값을 차례차례 사용하는 행위를 "traverse(순회)"라고 부른다.

 

자료구조를 조작하는 Helper Class의 사용에 친숙해져야한다!
배열의 Helper Class - Arrays

 

 

인덱스 연산자 [  ]

- 인덱스는 0부터 시작한다. 

- [ ] 는 배열 요소가 저장된 메모리의 위치를 찾아주는 역할을 한다.

 

 

배열의 길이

- 배열에 저장할 수 있는 전체 항목의 개수( .length )

※ 여기서 .length 는 읽기 전용(read-only) 필드이기 때문에 수정이 불가하다!

 

 


 

다차원 배열

- 2차원 이상으로 구현한 배열

- N차원 배열에서 데이터에 접근하려면 N개의 인덱싱 기호가 필요하다.

   (따라서, 인덱싱 기호 [ ] 의 개수를 보면 몇 차원 배열인지 알 수 있다)

- 다차원 배열의 변수 또한 참조타입이기 때문에 객체의 주소값을 가지고 있다.

타입[ ][ ]  변수명 = new 타입[행의 길이][열의 길이]

 

※ 자바는 1차원 배열 객체를 이용하여 다차원 배열을 구현한다.

   쉽게 말해서 1차원 배열 객체 요소를 배열로 주는 것이니까!!

   아래 코드를 통해 그 원리를 이해해보자!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Log4j
public class TTTT {
 
    
    public static void main(String[] args) {
        int[]     intArray = {123456};                      //1차원 배열
        log.info(intArray[0]);    //1
        
        int[][]   intArray2 = { { 123}, { 456} };             //2차원 배열
        log.info(intArray2[0]);        //배열[0] 객체의 주소값 출력
        log.info(intArray2[0][0]);    //1
        log.info(intArray2[1][1]);    //5
        
        int[][][] intArray3 = { {{1}, {2}, {3}}, { {4}, {5}, {6}} }; //3차원 배열
        log.info(intArray3[0]);            //배열[0] 객체의 주소값 출력
        log.info(intArray3[0][0]);        //배열[0][0] 객체의 주소값 출력
        log.info(intArray3[0][0][0]);    //1
        log.info(intArray3[1][1][0]);    //5
        
    }    //main
    
}    //end class
cs

 

 

◆ 객체 배열

- 기본타입 배열은 각 항목에 직접 값을 가지고 있으나,   

   참조타입(클래스, 인터페이스)인 배열은 각 항목에 객체의 번지(주소값)을 가지고 있다.

- 객체 배열 간의 값을 비교할 때 eqauls( ) 연산자를 사용해야 한다.

- 객체 배열을 호출하는 메소드를 생성하여 불러줘야 요소 값을 출력할 수 있다.

 

 

◆ 배열 복사  

- 얕은 복사(Shadow copy, Shallow copy, Thin copy)
   : 소스 객체를 변경, 복사한 타겟객체로 함께 동일하게 변경됨.

- 깊은 복사(Deep copy)
   : 원본객체와 복사된 타겟 객체 간에 연결성이 없이 복사

 

 배열객체 변수를 대입하여 복사할 수 있으나, 배열 객체의 주소값만 복사하기 때문에

  기존 배열의 인스턴스 값이 변경되면 두 배열 모두 영향을 받는다.

  따라서 인스턴스를 따로 생성한 후 요소의 값을 복사해야 한다.

 

방법1. for문 사용

- 새로운 배열 생성 후, for문 안에서 새로 생성된 배열에 기존 배열 요소 값을 대입

 

방법2. System.arraycopy( )메소드를 사용

- System 클래스에 있는 System.arraycopy( ) 메소드 활용

- System.arraycopy(원본배열, 복사할 배열의 첫번째 인덱스, 대상배열, 붙여 넣기를 시작할 첫번째 인덱스, 요소 개수)

 

방법3. Arrays 클래스 이용

- Arrays클래스에 있는 Arrays.copyof( )메소드 활용

- Arrays.copyof( )메소드 자체가 복사한 배열을 리턴해주기 때문에

  배열객체 생성을 분리할 필요가 없다!!!

 

 

 향상된 for문(Enhanced for)

- 배열에서 꺼낸 요소를 저장할 수 있는 변수 선언과 콜론( : ) 그리고 배열을 나란히 작성한다.

- 기존 for문에 있던 루프카운터 변수와 증감식을 사용하지 않는다.


※ 배열 전체를 traverse(순회)할 때 사용한다.

 

 

관련글 더보기