Collection, ArrayList, HashTable

 

Collection

1. Collection의 이해

1) 배열의 경우 인덱스를 사용하여 각 항목(element)에 접근하게 되는데, collection은 인덱스를 사용하지 않고 모든 element에 순차적으로 접근할 수 있는 방법을 제공하는거야.

2) element에 순차적으로 접근할 수 있도록 허용하는 객체의 집합이야.

3) 객체가 열거자(enumerator)라고 불리는 객체의 참조를 제공하면 collection이라 해.

4) 열거자는 collection 내의 항목을 순차적으로 액세스할 수 있어.

5) Foreach를 통해 객체내에 순차적으로 접근할 수 있도록 기능을 제공한다.

 

 

2. Collection의 동작

1) collection foreach 와 함께 사용될 때 foreach는 자동적으로 collection IEnumerable interface로부터 GetEnumerator() method를 호출

2) GetEnumerator() Ienumerable interface를 구현한 열거자 객체(enumerator object) return

3) foreach는 이 열거자 객체로부터 IEnumerable interface를 얻어 method(MoveNext(), Reset()) property(Current)를 호출

 

 

3. Custom Collection

 1) collection을 만들려면 System.Collections namespaceIEnumerable interface를 구현해야해.

IEnumerable interface

{

IEnumerable GetEnumerator();     //    열거자 객체를 반환

// 얘가 제공되어야지만 collection이라고 불릴 수 있는거야.

}

 2) 열거자 객체는 System.CollectionIEnumerable를 구현하는거야.

Interface IEnumerator

{

object Current { get; }  // Current 라는 프로퍼티는 get이라는 접근자만 제공하고 있어.

bool MoveNext();  

void Reset();

}

 

 

4. Custom Collection 작동모습

 1) IEnumerator를 구현한 class의 객체는 다음과 같이 작동을 구현해.

    (1) 객체 초기화시 어떤 element(항목) 가리키지 않음

(2) MoveNext method를 호출하여 첫번째 element로 이동.

(3) Current property를 통해 element를 뽑아내는거야.

    - Current property는 객체의 reference return하므로 이것을 찾고자 하는 객체의 형식으로 cast해서(안에 저장된 데이터의 타입으로) 필요한 작업을 수행

(4) MoveNext를 호출하여 다음 element로 이동

(5) 위 과정을 마지막까지 반복.

(6) Current property null return 하면 더 이상 접근할 항목이 없다는 의미

   (그래서 항상 루프를 돌릴 때 Current null인지 아닌지를 체크해야해)

(7) Reset method 를 호출하여 처음으로 돌아가거나 , 처리종료

(8) Reset 호출시에는 첫번째 element 의 이전을 가르키므로 MoveNext를 통해서 첫번째 항목으로 이동해서 순차적으로 접근을 해야해.

 

 

 

 

ArrayList

1. ArrayList의 이해

1) 객체를 배열로 만들어 사용하는데 유용한 기능을 제공

2) 확장성이 뛰어나 삽입/삭제/열거 등의 기능을 제공

3) 배열의 크기를 초기에 지정할 수 있어.

4) 정의된 크기를 초과하면 자동으로 크기를 늘려줘.

 

 

2. ArrayList Collection의 관계

1) ArrayList라는 자체가 IEnumerable interface를 통해서 구현된 클래스야. (상속을 받어)

  때문에 ArrayList GetEnumerator를 통해 열거자객체를 얻을 수 있어.

  (여기서도 foreach문을 사용할 수 있게 되는거야)

2) 이를 통해 순차적으로 ArrayList에 접근할 수 있어.

 

 

3. ArrayList 사용법

1) 생성 및 초기화

  ArrayList myAL = new ArrayList();   // ArrayList 생성

  myAl.Add(new Car(“그랜져”, 100000));    //  초기화, Car type data ArrayList에 저장

myAl.Add(new Car(“체어맨”, 200000));

myAl.Add(new Car(“포텐샤”, 300000));

 


 

2) ArryList 정보

  myAL.Count;  //  실제로 저장된 element

  int MaxSize = myAL.Capacity;     //  Capacity가 하는 일은 현재 ArrayList 총 크기 얻기지.

  myAL.Capacity = 20;   //   저장될 수 있는 총 용량 설정(default 16)

 

 

3) element(항목) 제거

  myAL.RemoveAt(1);   //  0부터 시작해서 지정된 요소를 제거, 1이면 두번째위치의 녀석이지

 

 

4) ArrayList를 배열로 변환

  - parameter를 배열로 전달해야 하는 경우에 사용(Type 변환 주의)

Car[] CarArray = new Car[myAL.Count];  //  저장될 배열 생성

for(int i=0; i<myAL.Count; i++) {     //   배열에 ArrayList 정보 저장

CarArray[i] = (Car)myAL[i];  // Car type으로 명시적 형변환하고 있어. 꼭 형변환해야해

}

foreach(Car i in CarArray) {    //  배열 출력

Console.WriteLine(“차종 : {0}, 가격 : {1}”, i.carName, i.carPrice);

}

 

 

 

 

 

HashTable

1. HashTable의 이해

1) 특정 Key 값에 의해 element에 접근할 수 있도록 고안된 데이터 구조

2) 어떠한 형태의 객체든 저장이 가능해(ArrayList도 가능해)

  Hashtable hash1 = new Hashtable();    //  HashTable 객체 선언

 

  Hash.Add(“847361”, “홍길동”);    //  Add method를 통한 등록

Hash.Add(“127561”, “박길동”);   // 첫번째가 키값, 두번째가 항목에 들어갈 데이터

Hash.Add(“887261”, “김길동”);

Hash.Add(“234561”, “이길동”);   

 

    foreach (string item1 in hash1.Keys) {   //  key data type에 의한 foreach 출력

           // 위에 놈은 위 string인가. 그건 홍길동의 type string이기 때문이야

      Console.WriteLine(item1 + “    “ + hash1[item1]);

}

 

Collection, ArrayList, HashTabled 의 공통점은?

    비슷한 특징이 있어. 객체를 배열로 묶어서 저장하고 그 배열에 대해서 순차적으로 foreach문을 통해서 자동적으로 접근할 수 있도록 기능을 제공하고 있지.

 

--------------------------------------------------------------------------------------------------------------

, 이제 예문을 통해 알아보자.

 

■ Collection

 

using System;


// 기본적인 기능을 가지고 있는 Collection를 만들어볼꺼야 #################
class MyCollection
{

 // 보통은 private로 많이 하나 예제니 간단하게 public으로 만들자
 public int[] items;     //   배열 생성
 int nIndex = -1;         //   변수 생성

 MyCollection collection;  // 변수 생성..... 안에서 items를 계속 접근할려고 만들었어.


 //  생성자에서는 collection에다가 현재객체를 담도록 지정해볼꺼야.
 public MyCollection()
 {
  collection = this; //  여기에는 Reference가 담기게 되는거야.
 }


 public MyCollection GetEnumerator()
 {
  return this;  //   MyCollection를 리턴하도록 설정했어. 
 }


 //   이 MoveNext를 통해 이동하고 Current를 통해 데이터를 뽑아내는거야.
 public bool MoveNext()
 {
  nIndex++;
  return(nIndex < collection.items.GetLength(0));
   //   배열에 접근할 수 있는 배열첨자의 역할을 int type변수
 }


 public void Reset()
 {
  // nIndex 배열을 초기화해줄것
  nIndex = -1;
 }


 public int Current
 {
  get { return(collection.items[nIndex]); }
 }
}


// ######################################################


class MyClass
{
 public static void Main()
 {
  // 위에서 Collection을 만들었으니 객체를 만들어서 순차적으로 접근해보자.
  MyCollection col = new MyCollection();
  col.items = new int[5]{11, 33, 22, 55, 44};      
  //  5개의 int type Array 생성

  // 콜렉션같은 경우는 foreach문을 통해 순차적인 접근이 가능해.
  foreach(int i in col)
  {
   Console.WriteLine(i);
  }

 }
}


▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒


■ ArrayList

 

 // 학습목료
// : 학교에 등교하는 학생의 정보를 저장해볼꺼야.

using System;
using System.Collections; // -> 이 부분을 참조했어. (네임스페이스)

 

class Student
{
 // 멤버들을 기술할꺼야. 예제를 위해 public으로 구성할꺼야.
 public string name; // 학생 이름
 public int no;      
   //  학생 번호

 

 // ###생성자를 생성###
 public Student(){}


 public Student(string name, int no)
 {
  this.name = name;       // 초기화
  this.no = no;          
   // 초기화
 }
}


class Myschool
{
 public static void Main()
 {
  // 나왔다. ArrayList ~
  ArrayList myAL = new ArrayList();


  // 어짜피 레퍼런스타입으로 저장되기에 new를 사용했어.
  myAL.Add(new Student("홍길동", 20));      //  학생 객체를 Array를 통해 생성
  myAL.Add(new Student("지니진", 10));
  myAL.Add(new Student("이순신", 30));


  // 홍길동을 삭제할꺼야~
  myAL.RemoveAt(0);



  // 그럼 출력해보자.
  // 현재는 Student type Data를 가지고 있어. 우리는 ArrayList 자체가 아니라 Student 객체에 대한 데이트들.
  // 그래서 Student type으로 변환해야해.
  for(int i=0; i<2; i++)
  {
   // 여기서 Student type으로 형변환을 해줄꺼야
   Console.WriteLine("이름 : {0}, 번호 : {1}", ((Student)myAL[i]).name, ((Student)myAL[i]).no);
  }



  Console.WriteLine();

  // 이번에는 배열로 바꿔보자. -------------------------------------------------------------------------------------------
  // Student 라는 클래스에 데이터가 들어가 있어.  배열로 Student type으로 배열로 만들꺼야.
  Student[] StudentArray = new Student[myAL.Count];  // 객수만큼 만들어.. 2인 배열이 생성되겠지

  // for문을 통해서 알아보자
  for(int i=0; i<myAL.Count; i++)
  {
   // Student Array 에 Student type으로 저장하는거야.
   // 파라미터나 foreach문으로 출력이 가능해

   StudentArray[i] = (Student)myAL[i];
  }


  foreach(Student i in StudentArray)
  {
   Console.WriteLine("이름 : {0}, 번호 : {1}", i.name, i.no);
  }


 }
}



▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒


■ HashTable

 

// 학습목료
// : 학교에 등교하는 학생의 정보를 저장해볼꺼야.



// ArrayList 같은경우 아이이뉴멀오프 인터페이스를 실제로 구현하면
// foreach문을 통해 접근할수 있어.

using System;
using System.Collections; // -> 이 부분을 참조했어. (네임스페이스)


class MyHashTable
{
 public static void Main()
 {
  // 배열같은 경우는 인덱스값이 int type만 가능하나 해쉬 테이블을 달라
  // 문자열이나 기타 다른 타입으로도 가능하다는 거야.

  Hashtable hash1 = new Hashtable();


  hash1.Add("111111", "홍길동");   // 앞이 키값, 뒤가 항목
  hash1.Add("222222", "임꺽정");
  hash1.Add("333333", "이순신");

 

  // 그럼 출력해보자
  foreach(string item in hash1.Keys)
  {
      Console.WriteLine(item + "         " + hash1[item]);
  }



  // 항목을 삭제해보자.
  hash1.Remove("222222");
  foreach(string item in hash1.Keys)
  {
   Console.WriteLine(item + "         " + hash1[item]);  // 임꺽정이 지워진것을 알수있어.
  }


 }
}


▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

신고
Posted by 나비 나비:D

보통은 컬렉션을 배열로 구현을 하는게 맞다.

사용하는 입장이라면 기존의 있는 자료형을 그대로 쓰는게 좋겠지.

우리는 컬렉션을 다루기가 쉽거든.


배열과 컬렉션의 선택기준

단일타입의 집합은 배열을 쓰자.

배열은 막무가내로 짜지 않는다. 중학교 관리프로그램이라고 치면 어느정도 예상치를 알기에

적정하게 잡고 만들지.

다중타입의 집합은 컬렉션을 쓰자. 가변적인 방의 갯수.. 배열과 달리 줄이거나 늘리는데 유동적.


배열이나 컬렉션을 만들고 탐색을 많이 하지.

아이템에 대한 접근을 하는데 배열은 for문을 쓰고 컬렉션은 foreach문 쓰자. 실제 컬렉션은 for문

 보다 foreach문이 월등히 빠르다.

                                   




배열과 컬렉션의 차이점.

    [배열]

     : 데이터의 집합, 배열도 오브젝트형을 만들 수 있다. 배열은 고정된 크기만 갖는다.

       첨에 방이 10개면 계속 10만 가능하다.


    [컬렉션]

     : 다중 데이터형 집합, 오브젝트형의 집합

       동적으로 메모리 확장가능(크기가 가변적이다, 가장 많이 쓰는 이유)

              확실하지 않은 데이터의 크기는 컬렉션을 많이 쓰지.

              방을 늘리거나 줄이거나 가능하기 때문이야




ArrayList

     - 크기가 필요에 따라 동적으로 증가되는 배열

     - 데이터를 넣을때

          list.Add();


     Ilist      :  아이리스트를 부모로 갖는(상속) 놈들은 인덱서를 쓰도록 하자

                   Array list = new Array();    ->   list[0]

                   이런 방법으로 입/출력할 수 있는 것.

     ICollection    :   얘를 상속받은 모든 클래스는 자기가 가지고 있는 구성요소를 count

                                   라는 이름으로 반환하게 되어 있어.

                                   쩜.count  이런 식으로 쓰인다.

     IEnumerable : 도움말 참조~

     ICloneable : clone 이라는 메소드를 구현해야 한다. 왜 배열을 clone으로 카피하는 이유

                              list.clone();     복사할 때 이런 문법을 쓰는데 이 인터페이스를 상속받았기

                              때문이야.




개념을 알고 가자

Add :  추가의 개념, 다른 메소드에서는 Append 라고도 한다. 내용이 있으면 밑에다 계속 추가.

Insert : 삽입의 개념. 자료가 있으면 사이에 비짚고 넣겠다는 거야.

가변적인 ArrayList  왜???

    배열은 방을 만들면 끝이다.  int[] num = new int[5];

    그러나 이놈은 신기하게 방갯수 변경이 가능하다. 하지만 이놈도 원래 방의 크기가 있다.

    ArrayList mm = new ArrayList();

    list.Add(10);

    list.Add(20);

    list.Add(30);

          원래 기본적으로 3개의 방이 생성이 되는데 4번째 방을 만들고자 Add로 넣으면

          기본크기의 2배가 되는 방을 만들고 원래있던 값들을 복사한다.

    list.Add(40);

          내부적으로는 객체가 2번 생성이 된것이지.. 그리고 방의 크기는 6개가 되는거야.

          보통 기본크기도 잡을 수 있다.

          근데 항상 요소의 갯수가 100개와 101개를 넘나들면 빈방이 많아지겠지.

          이까지는 좋아. 4번째방에 40을 넣으면 2개의 남는 방이 있잖아.

          이 때, 죽어도 4개이상의 방을 넘어갈 일이 없다... 즉 남는방을 없앨 때

          우리는 list.TrimToSize();  를 써서 공간낭비를 줄일 수 있다.



========================================================================================



using System;
  using System.Collections;   //  컬렉션을 구동하기 위해 추가하는 using문

    namespace ConsoleApplication1
    {
       public class Class6
       {
          public static void Main(string[] args)
          {
           // 배열같은 놈을 하나 만들자
           // #### ArrayList #########
           // 배열과 달리 길이가 가변적이라 방의 갯수를 지정할 필요 없다.
           //    foreach문을 지원한다.
           ArrayList list = new ArrayList();
           list.Add(100);
           list.Add(200);
           list.Add(300);
           Console.WriteLine("list의 크기 : {0}", list.Count); //  3 을 반환
           Console.WriteLine(list[1]);     //   200 을 반환
           foreach(int n in list)
           {
                 Console.WriteLine(n);      //  100    200    300    을 반환
           }


           // 요소를 모두 제거하는 clear
           list.Clear();
           Console.WriteLine(list.Count);        //      0      을 반환


           // 지운 값을 다시 넣고...
           list.Add(100);
           list.Add(200);
           list.Add(300);


           // 유/무를 반환, 검색용 메소드
           Console.WriteLine(list.Contains(200));       // true를 반환


           // Insert....
           list.Insert(1,400);        //     1번째 위치에 400을 넣겠다는 의미다.
           foreach(int n in list)
           {
                 Console.WriteLine(n);
           }


           // Insert를 ADD랑 같게 만들고 싶다면
           list.Insert(list.Count, 777);
            foreach(int n in list)
            {
                   Console.WriteLine(n);
            }


           // Remove는 찾아서 지우는 놈.... 200을 넣으면 200이란 값을 찾아서 지운다.
           // 만약 200이 두개 있으면 첫번째 놈만 지운다.
           list.Remove(200);


           // 찍어서 지운다.
           list.RemoveAt(1);


           // sort는 배열의 sort와 같다.
           list.Sort();


           // 이놈은 쓰는게 좋다.
           //       왜 이 ArrayList란 놈은 가변적일까???
           //              그 질문과 연장선상에 있다. 이놈은 남는 방을 잘러버리거든      
           list.TrimToSize()



▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒


HashTable

    IDictionary 기능을 가지고 있다. 방이름(키값)을 지정해주는것

    이 놈은 hash[0] 이라고 하면 0번째 방이 아닌 0의 키값을 가지는지 보는거야..

    패턴이 없기 때문에 반복시키기가 좀 애매해.. 못하는건 아닌데 많이 까다로워

    직관적인 대신에 이런 약점을 가지지...


    list[0]    -     "스칼라배열", 인덱스로 구분

    list["id"] -     "연관배열", HashTable



   // 사용자의 입장에서 주소값만 보고는 사실 머가 들어있는지 잘 모르잖아
   // 근데 방이름만 잘 정해주면 방속에 있는 데이터가 먼지를 어느정도 알수있잖아~
   Hashtable hash = new Hashtable();
   hash.Add("one", "하나");
   hash.Add("two","둘");
   hash.Add("three","셋");
   hash.Add("402","닷넷전문가");
   hash.Add("301","DB전문가");


   // Hashtable을 불러내기 위해서는 방의 이름표(키값)를 요구한다.
   //     ADD 할때 키와 값의 쌍으로 이루어지게 된다.
   Console.WriteLine(hash["one"]);
   Console.WriteLine(hash["402"]);
   Console.WriteLine(hash[0]);      //   0번째 방이 아닌 0의 키값을 찾아보는거다.


   //  Queue, 입/출력 데이터는 역시 오브젝트이다.
   //      선입선출(FIFO : first in first out)  :  파이프에 공을 넣고 끝에서 하나씩 받는다고 생각해.
   //                  우리가 쓰는 원도우에 딜레이가 있어도 먼저 클릭한 것부터 진행하잖아~
   //                  이는 메시지를 담아놓는 Queue가 존재해서 그래.

   Queue queue = new Queue();
   queue.Enqueue(10);
   queue.Enqueue(20);
   queue.Enqueue(30);     // 차곡차곡 순서대로 데이터를 넣었다.

   //  데이터를 끄집에 낼때는 단순한 메소드 호출 10->20->30의 순서로 호출된다.
   Console.WriteLine(queue.Count);            //      3 이 호출
   Console.WriteLine(queue.Dequeue());
   Console.WriteLine(queue.Dequeue());
   Console.WriteLine(queue.Dequeue());
   Console.WriteLine(queue.Count);      //     0 이 호출 : Dequeue()라는 놈은 가져온 만큼 데이터 소멸
   
   queue.Enqueue(500);
   Console.WriteLine(queue.Peek());  //  요소를 제거하지 않고 그냥 반환.. 데이터 소멸 X
   Console.WriteLine(queue.Count);   //    1 이 호출


   // Stack =========================================================
   //        후입후출(LIFO : last in first out) 맨 마지막에 들어간 놈이 맨 첨에 나온다.
   //        바닥이 막힌 세로로 생긴 통이라고 생각해라.

   Stack stack = new Stack();
   stack.Push("일");
   stack.Push("이");
   stack.Push("삼");
   Console.WriteLine(stack.Count);   //     3 이 호출
   Console.WriteLine(stack.Pop());   //      "삼"  이 호출
   Console.WriteLine(stack.Pop());   //     "이"  가 호출
   Console.WriteLine(stack.Pop());   //     "일" 이 호출
   Console.WriteLine(stack.Count);      //      0 이 호출
   
   stack.Push("십");
   Console.WriteLine(stack.Peek());      //   "십" 이 호출
   Console.WriteLine(stack.Count);       //     1    이 호출







▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒


          }
     }
}

신고
Posted by 나비 나비:D

BLOG main image
by 나비:D

공지사항

카테고리

분류 전체보기 (278)
Programming? (0)
----------------------------- (0)
나비의삽질 (5)
Application (177)
SQL (51)
Web (27)
etc. (14)
Omnia (0)
---------------------------.. (0)

글 보관함

달력

«   2017/10   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
Total : 882,504
Today : 0 Yesterday : 218