◆ 배열이란?
- 같은 타입의 데이터를 연속된 메모리 공간에 저장하는 자료구조
- 각 데이터 저장 위치는 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 = {1, 2, 3, 4, 5, 6}; //1차원 배열
log.info(intArray[0]); //1
int[][] intArray2 = { { 1, 2, 3}, { 4, 5, 6} }; //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(순회)할 때 사용한다.