* 배열 Array
- 배열객체 : 동일한 자료형의 고정된 갯수의 공간(배열)을 갖고 있는 객체- 유사한 여러변수들을 하나의 묶음(배열)으로 다루는 객체
- 배열의 원소는 기본형,참조형이 모두 가능.
# 배열의 선언
- 배열변수의 선언: 배역객체의 reference를 저장하라 수 있는 참조변수의 선언.- 배열원소의 자료형과 배열기호[], 그리고 배열(참조) 변수명으로 구성.
(배열 원소의 자료형은 기본형과 참조형 둘다 가능)
- 형식 : 자료형[] 배열변수명
예) int i[]; //int형 배열변수 i선언
String st[]; // String형 배열변수 st선언
# 배열의 생성(1)
- 자료를 저장하기 위한 공간(배열)을 갖고 있는 객체의 생성과 그 객체의 reference를 배열(참조)변수에 대입하는 절차.- 키워드 new와 함께 배열의 타입과 크기를 지정.
- 배열의 원소들은 초기값으로 초기화.
# 배열의 생성(2)
형식 - 배열변수명 = new 자료형[배열의길이]
예) i = new int[10];
/*
배열객체의 생성과 초기화, 그리고 참조변수 i에 대입
(이 배열객체는 int형의
*/
// int jumsu[] = new int[]{95,84,87,92,100,90,78,94}; //표기법1
// int jumsu[] = {95,84,87,92,100,90,78,94}; //표기법2
// int[] jumsu = {95,84,87,92,100,90,78,94}; //표기법3
int jumsu[] = new int[8]; //표기법4
int idx = 0;
jumsu[idx++] = 95;
jumsu[idx++] = 84;
jumsu[idx++] = 87;
jumsu[idx++] = 92;
jumsu[idx++] = 100;
jumsu[idx++] = 90;
jumsu[idx++] = 78;
jumsu[idx++] = 94;
// int jumsu[] = {95,84,87,92,100,90,78,94}; //표기법2
// int[] jumsu = {95,84,87,92,100,90,78,94}; //표기법3
int idx = 0;
jumsu[idx++] = 95;
jumsu[idx++] = 84;
jumsu[idx++] = 87;
jumsu[idx++] = 92;
jumsu[idx++] = 100;
jumsu[idx++] = 90;
jumsu[idx++] = 78;
jumsu[idx++] = 94;
# 메모리상의 배열(1)
- 메모리에 배열이 생성되는 과정은 다음과 같음
예) int[] items;//배열객체의 regerence를 대입.
items = items int[5];//배열객체의 생성및 초기화/ reference를 대입.
Heap 영역에 ,배열을 포함하는 (배열)객체가 생성되고
배열은 4Byte의 연속된 메모리가 할당되고 초기화 됨.
<stack영역> < Heap영역>
items[0]
reference값 : 0x100 ↗ items[1]
/ items[2]
/ items[3]
items(null) / items[4]
# 배열의 특징
- 배열의 선언과생성을 한문장으로.
형식 : 자료형[] 변수이름 = new 자료형[길이];
- 배열은 한번 생성되면 길이를 바꿀 수 없음.
- 각 배열원소들은 초기값으로 초기화 된다.
예) 논리형 → false
정수형 → 0
실수형 → 0.0
문자형 → \u0000
참조데이터형 → null
# 배열의 초기화(1)
- 개별적인 초기화
- int[] items = new[5];
- items[0] = 100;
- items[1] = 90;
- 집합적인 초기화
- new 키워드를 사용하지 않는 방법
- int[] items = {1,2,3}
- new 키워드를 사용하는 방법
- int[] items = new int[] {1,2,3}
- 1,2 의 차이?
- 1 처럼 하면 선언할때만 초기화 가능
- 2 는 선언 따로 하고 초기화 별도로 가능함.
# 배열의 사용
- 배열의 각 원소는 배열참조변수와 인덱스를 사용해서 접근.
- 인덱스란?
배열의 저장공간에 순서대로 자동적으로 주어지는 번호, 0부터 연속적으로 증가하는 정수값.
예) 크가가 5인 배열의 index의 범위는 0~4
# 배열의 사용(2)
- 형식: 참조변수명[인덱스]
예1) ages[1] = 20;
//배열참조변수 ages가 가리키는 배열의 두번째 원소에 값 20 eodlq
예2) int ages = ages[1]
// 정수형 변수 age를 선언하고
// 배열참조변수 ages를 배열의 두번째 원소의 값으로 초기화.
# 배열의 사용(3)
- for 문으로 배열에 접근할때는 배열의길이(length)를 이용한다.
예)
for(int i=0;i<ages.length;++i) {
...
}
- (참고)배열도 객체이며,멤버필드와 메서드를 갖고있다.
-------------
- 실습(한시간 넘게)
교재 : p129~
-------------
# 그 밖의 배열
1. 다차원배열 : 2차원 이상의 배열을 말하며 ,이러한 배열을 갖고 있는 객체.
- 2차원 배열
2. 가변배열 : 2차원 이상의 배열로서 각 행마다 열의 크기가 다른 배열.
- 2차원 가변배열
먼저 배열을 선언하는 것과 동시에 초기화 하는 방법입니다.
int[ ][ ] a = new int[ ][ ] { 1, 2, 3 }, { 6, 7, 8 } ;
int[ ][ ] a = { { 1, 2, 3 }, { 6, 7, 8 } } ;
int[ ][ ] a = new int[ ][ ] { 1, 2, 3 }, { 6, 7, 8 } ;
int[ ][ ] a = { { 1, 2, 3 }, { 6, 7, 8 } } ;
- 다차원배열(1)
- 선언:자료형,차원만큼의[],그리고 배열참조변수 이름으로 구성.
- 형식:자료형[][]배열(참조) 변수명
- 예-int[][] grades;
- [] 위치는 자료형 다음 또는 변수 다음.
- 다차원배열(2)
- 생성 : 첫번째는 행 두번째는 열
- 형식 : 배열변수명 = new자료형[행][열길이]
- 예- int[][] grades = new int[2][3]; 행 열
- 다차원배열(3)
- 배열변수 grades를 위한 공간 생성과 초기화
- reference를 담을 수 있는 길이가 2인 reference배열 객체의 생성과 초기화
- 자료를 담을수 있는, 길이가 3인 int배열객체의 생성과 초기화, 그리고 이 배열객체의 reference를 먼저 생성된 ref 배열에 대입x(2회)
- reference배열 객체의 reference를 배열변수 grades에 대입.
- 다차원배열(4)
- 초기화
- 형식 : 배열변수 = new자료형[][]{{},{}}
- 예) 배열변수 = new 자료형[][]{{}{}}
- 초기화를 할때는 ,배열의 갯수를 명시하지 않는다.
- 다차원배열(5)
- 행과 열의 인덱스를 사용하여 원소에 접근하고,배열객체의 length필드를 활용.
- 예) grades[1][0]=80;//1행1열에 80대입.
- 예) int sum=grades[1][0]+grades[1][1]+grades[1][2];
- 배열참조변수.length → 2차원배열의 행의길이(=reference배열길이)
- 배열참조변수[행].length → 지정된 행의 열의길이.
- 예) grades.length //grades배열의 행의 길이
- 예) grades[0].length //grades배열의 첫번째 행의 열의 길이
- 예) grades[1].length //grades배열의 두번째 행의 열의 길이
가변배열(1)
- 가변배열 선언 및 생성.
- 배열의 열의 길이가 일정하지 않은 배열을 포함하는 객체
- 배열의 마지막 차원의 크기를 나중에 지정.
- 효율적인 배열의 구성을 허용
- 예) int maps[][] = new int[4][];//마지막 차원이 지정되지 않음
- maps[0] = new int[3]; //열의 길이지정 및 생성
- maps[1] = new int[4]; //열의 길이지정 및 생성
- maps[2] = new int[5]; //열의 길이지정 및 생성
- maps[3] = new int[5]; //열의 길이지정 및 생성
- 가변배열 초기화
- 예) int maps[][] = new int[][] {
- {1,2},
- {1,2,3},
- {1,2,3,4},
- {1,2,3,32}
- };
- 생성과 초기화를 같이할때 => 배열의 갯수를 명시하지 않는다.
# 배열의복사
- for 문을 이용한 직접복사 → deep copy
- 배열의 clone 메서드 이용
- 혹은 System.arraycopy() 이용
- (1차원 배열 deep copy, 2차원배열 shallow copy)
- 형식
- System.arraycopy(source 배열,시작위치,타겟배열,시작위치,복사할 배열의길이)
* 용어정리 (A를 B에 카피할 때)
- deep copy → A 변경시 B 불변
- (원본과 같은 데이터를 저장하고 있는 새로운 객체나 배열을 생성하는것)
- shallow copy → A변경시 B 변경.
- 배열이나 객체를 복사할 때, 단순히 참조만 복사하는 것.
Shallow Copy: 참조형 변수가 가지고 있는 참조값을
복제한다.
Deep Copy : 참조형 변수가 참조값에 의해 참조하고 있는 인스턴스 자체를 복제하여 새로운 인스턴스를 만든다.
다음은 참조형의 일종인 배열형 변수에 대한 Shallow Copy와 Deep Copy의 차이점을 보여주는 간단한 코드다.
public class Exam_Copy2 {
public static void main(String[] args) {
int array[] = new int[]{1,2,3,4,5};
//array가 가리키는 배열 인스턴스에 대한 참조값만을 복사한다.
int shallowCopy[] = array;
//새로운 배열 인스턴스를 만들어 array가 가리크는 배열 인스턴스의 내용을 복사한다.
int[] deepCopy = new int[array.length];
System.arraycopy(array,0,deepCopy,0,array.length);
array[2] = 123;
System.out.println(shallowCopy[2]);
System.out.println(deepCopy[2]);
}
}
-------------------------------------------------------------------------------------
123
3
-----------------------------------------------------------------------------------
참조 값만을 복제한 shallowCopy는 결국 array와 같은 배열 인스턴스를 가리키고 있으므로 "array[2]=123" 을 통해 변경한 결과가 반영되어 shallowCopy[2]의 값 역시 "123"이 될 것이나 배열 인스턴스의 내용 자체를 복사하여 새로운 인스턴스를 가지고 있는 deepCopy는 array[2]의 변화에 상관없이 복제 당시의 값인 3을 출력하는 모습을 볼 수 잇다.
살펴본 바와 같이 참조형 변수를 복제한다고 할 때에 그 의미가 Shallow Copy인지 Deep Copy인지 구별하는 것은 중요하다. 하지만 참조형 변수라고 해서 항상 이러한 구별을 해야 하는것은 아니다. 생성된 후에는 그 값이 구별할 수 없는 특징을 가지는 이뮤터블 클래스의 인스턴스에 대해서는 Shallow Copy , Deep Copy와 같은 구별이 무의미하다. 이뮤터블 클래스의 인스턴스는 그 자체로서 값형 변수와 같은 특징을 갖기 때문이다. 그러한 이유로 이뮤터블 클래스의 인스턴스를 값 객체(Value Object)라고 부르기도 한다..
Deep Copy : 참조형 변수가 참조값에 의해 참조하고 있는 인스턴스 자체를 복제하여 새로운 인스턴스를 만든다.
다음은 참조형의 일종인 배열형 변수에 대한 Shallow Copy와 Deep Copy의 차이점을 보여주는 간단한 코드다.
public class Exam_Copy2 {
public static void main(String[] args) {
int array[] = new int[]{1,2,3,4,5};
//array가 가리키는 배열 인스턴스에 대한 참조값만을 복사한다.
int shallowCopy[] = array;
//새로운 배열 인스턴스를 만들어 array가 가리크는 배열 인스턴스의 내용을 복사한다.
int[] deepCopy = new int[array.length];
System.arraycopy(array,0,deepCopy,0,array.length);
array[2] = 123;
System.out.println(shallowCopy[2]);
System.out.println(deepCopy[2]);
}
}
-------------------------------------------------------------------------------------
123
3
-----------------------------------------------------------------------------------
참조 값만을 복제한 shallowCopy는 결국 array와 같은 배열 인스턴스를 가리키고 있으므로 "array[2]=123" 을 통해 변경한 결과가 반영되어 shallowCopy[2]의 값 역시 "123"이 될 것이나 배열 인스턴스의 내용 자체를 복사하여 새로운 인스턴스를 가지고 있는 deepCopy는 array[2]의 변화에 상관없이 복제 당시의 값인 3을 출력하는 모습을 볼 수 잇다.
살펴본 바와 같이 참조형 변수를 복제한다고 할 때에 그 의미가 Shallow Copy인지 Deep Copy인지 구별하는 것은 중요하다. 하지만 참조형 변수라고 해서 항상 이러한 구별을 해야 하는것은 아니다. 생성된 후에는 그 값이 구별할 수 없는 특징을 가지는 이뮤터블 클래스의 인스턴스에 대해서는 Shallow Copy , Deep Copy와 같은 구별이 무의미하다. 이뮤터블 클래스의 인스턴스는 그 자체로서 값형 변수와 같은 특징을 갖기 때문이다. 그러한 이유로 이뮤터블 클래스의 인스턴스를 값 객체(Value Object)라고 부르기도 한다..



댓글 없음:
댓글 쓰기