2013년 8월 8일 목요일

08.08 - 오후 : 배열 Array

* 배열 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;

# 메모리상의 배열(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)

  1. 개별적인 초기화
    1. int[] items = new[5];
    2. items[0] = 100;
    3. items[1] = 90;
  2. 집합적인 초기화
    1. new 키워드를 사용하지 않는 방법
      1. int[] items = {1,2,3}
    2. new 키워드를 사용하는 방법
      1. int[] items = new int[] {1,2,3}
    3. 1,2 의 차이?
      1. 1 처럼 하면 선언할때만 초기화 가능
      2. 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 } } ;
  1. 다차원배열(1)
    1. 선언:자료형,차원만큼의[],그리고 배열참조변수 이름으로 구성.
    2. 형식:자료형[][]배열(참조) 변수명
      1. 예-int[][] grades;
    3. [] 위치는 자료형 다음 또는 변수 다음.
  2. 다차원배열(2)
    1. 생성 : 첫번째는 행 두번째는 열
    2. 형식 : 배열변수명 = new자료형[행][열길이]
      1. 예- int[][] grades = new int[2][3]; 행 열
  3. 다차원배열(3)
    1. 배열변수 grades를 위한 공간 생성과 초기화
    2. reference를 담을 수 있는 길이가 2인 reference배열 객체의 생성과 초기화
    3. 자료를 담을수 있는, 길이가 3인 int배열객체의 생성과 초기화, 그리고 이 배열객체의 reference를 먼저 생성된 ref 배열에  대입x(2회)
    4. reference배열 객체의 reference를 배열변수 grades에 대입.
  4. 다차원배열(4)
    1. 초기화
      1. 형식 : 배열변수 = new자료형[][]{{},{}}
      2. 예) 배열변수 = new 자료형[][]{{}{}}
    2. 초기화를 할때는 ,배열의 갯수를 명시하지 않는다.
  5. 다차원배열(5)
    1. 행과 열의 인덱스를 사용하여 원소에 접근하고,배열객체의 length필드를 활용.
    2.   예) grades[1][0]=80;//1행1열에 80대입.
    3.   예) int sum=grades[1][0]+grades[1][1]+grades[1][2];
    4. 배열참조변수.length → 2차원배열의 행의길이(=reference배열길이)
    5. 배열참조변수[행].length → 지정된 행의 열의길이.
    6.   예) grades.length      //grades배열의 행의 길이
    7.   예) grades[0].length //grades배열의 첫번째 행의 열의 길이
    8.   예) grades[1].length //grades배열의 두번째 행의 열의 길이



가변배열(1)
  1. 가변배열 선언 및 생성.
    1. 배열의 열의 길이가 일정하지 않은 배열을 포함하는 객체
    2. 배열의 마지막 차원의 크기를 나중에 지정.
    3. 효율적인 배열의 구성을 허용
    4. 예) int maps[][] = new int[4][];//마지막 차원이 지정되지 않음
      1. maps[0] = new int[3]; //열의 길이지정 및 생성
      2. maps[1] = new int[4]; //열의 길이지정 및 생성
      3. maps[2] = new int[5]; //열의 길이지정 및 생성
      4. maps[3] = new int[5]; //열의 길이지정 및 생성
  2. 가변배열 초기화
    1. 예)  int maps[][] = new int[][] {
                1.     {1,2},
                2.     {1,2,3},
                3.     {1,2,3,4},
                4.     {1,2,3,32}
                5.  };
    2. 생성과 초기화를 같이할때 => 배열의 갯수를 명시하지 않는다.

# 배열의복사

  1. for 문을 이용한 직접복사 → deep copy
  2. 배열의 clone 메서드 이용
    1. 혹은 System.arraycopy() 이용
    2. (1차원 배열 deep copy, 2차원배열 shallow copy)
  3. 형식
    1. 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)라고 부르기도 한다..








































댓글 없음:

댓글 쓰기