글로벌 객체지향 프로그래밍 13주차 - C# 컬렉션
배열
개념
- 동일한 자료형을 저장 가능함
- 인덱스로 접근하여 데이터를 삽입 혹은 다른 값으로 변경이 가능함
컬렉션
개념
- 다양한 데이터를 저장 할 수 있음
- System.collections 네임스페이스를 선언하여 사용 가능함
종류
ArrayList
- 필요에 따라 크기가 동적으로 증가하는 개체 배열
- 배열과 유사한 컬렉션으로, Index로 값에 접근이 가능하며, 바로 읽거나 쓰는것이 가능함
- 모든 타입의 값을 저장할 수 있음
- 값을 가져올때 var형을 이용해 암시적으로 형 변환이 가능함
- 추가 / 삭제 / 변경 / 조회가 가능함
배열과의 차이점
배열은 생성시 크기를 지정함
ArrayList는 생성 이후 값의 추가 혹은 삭제에 따라서 크기가 동적으로 변화
메소드 속성 설명 Add(값) 저장(추가) ArrayList의 저장된 정보들 끝에 값을 추가함 Insert(위치, 값) 저장(추가) 원하는 Index의 위치에 값을 추가함
해당 위치에 있는 값부터, 뒤에 있는 값들은 전부 1칸식 자동으로 뒤로 이동됨Remove(값) 삭제 해당 데이터를 삭제함 RemoveAt(위치) 삭제 원하는 Index 위치의 값을 삭제함
삭제된 값의 뒤에 있는 값부터, 뒤에 있는 값들은 전부 1칸식 자동으로 앞으로 이동됨Clear() 삭제 저장된 모든 정보들을 삭제 Contains(값) 조회 ArrayList안에 데이터가 있는지 조회함 Count 조회 저장된 데이터의 총 갯수를 반환함 _ArrayList[위치] 접근 해당 ArrayList의 “위치”에 있는 값에 접근
예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void Main(string[] args)
{
ArrayList al = new ArrayList();
al.Add(1); //다양한 형식으로 값을 추가
al.Add("Hello");
al.Add(3.3);
al.Add(true);
foreach(var item in al)
Console.WriteLine(item);
Console.WriteLine("---------------");
al.Remove("Hello"); //Remove() 메소드로 아이템을 삭제함
foreach (var item in al)
Console.WriteLine(item);
}
Output
1
2
3
4
5
6
7
8
1
Hello
3.3
True
---------------
1
3.3
True
Hashtable
키의 해쉬 코드에 따라 구성된 키/값 쌍의 컬렉션
데이터를 키와 값으로 저장하는 구조
원문과 번역문의 쌍으로 저장되는 형태
데이터의 크기가 커질수록 상대적으로 처리하는 속도가 빠름
ArrayList, Stack, Queue는 저장된 데이터 순서가 중요함
But Hashtable은 키로 한번에 값을 찾을 수 있음
키는 어떤 타입(int, float, string, bool….)이든 사용 가능
But 같은 키가 있을 경우, “Argument Exception” 오류가 발생함
많은 데이터를 저장할 경우, ArrayList보다 빠른 속도로 “저장된 값”에 접근이 가능함
작동방식
전체 데이터 양이 16인 이름을 키로, 전화번호를 값으로 저장하는 해쉬 테이블을 만들 때,
index = hash_function(키 이름) % 16을 통해 Index 값을 구하고, array[16] = “키 이름의 전화번호 값”을 저장함
데이터를 저장 한 이후, Key에 대한 데이터를 찾을 때, hash function을 한번만 수행하면 array 내에 저장된 Index값을 찾을 수 있음
문제점
hash_function(key) / size_of_array의 값이 중복이 될 수 있음
Ex) 저장하고자 하는 key가 정수형이고 hash_function이 key%10일 때,
size_of_array가 10일 때, key 1,11,21,31은 같은 index값을 가지게 됨
이를 Collision(충돌)이라고 함
해결방법
다양한 구현 방식이 존재
Separate chaining 방식 - 각 Index에 데이터를 저장하는 Linked List에 대한 포인터를 가지는 방식
해시 충돌 발생 시 연결 리스트로 데이터들을 연결
장점:
연결리스트만 사용하면 되므로, 구현이 개방 주소법에 비해 비교적 간단함
개방 주소법 방식 - 해시 충돌 발생시 다른 버켓에 데이터를 삽입하는 방식
- 장점:
- 체이닝처럼 포인터가 필요하지 않고, 지정한 메모리와 추가적인 저장공간이 필요없음
- 삽입/삭제 시 오버헤드가 작음
- 지정할 데이터가 적을 때 더 유
- 장점:
ArrayList와의 차이점
- ArrayList: 데이터를 찾을때 Index로 값을 찾음
- HashTable: key로 value를 찾음
메소드 속성 정보 Add(키, 값) 저장(추가) Hashtable에 키와 값을 추가 Remove(키) 삭제 HashTable에 해당 데이터(키와 값)을 삭제 Clear() 삭제 저장된 모든 데이터를 삭제 Count 정보 현재 저장된 데이터의 총 쌍의 갯수를 조회함 ContainsKey(키) 정보 HashTable에 해당 키가 있는지 조회함
값이 있을경우 True
값이 없을 경우 FalseContainsValue(키) 정보 HashTable에 해당 **가 있는지 조회함
값이 있을경우 True
값이 없을 경우 Falseht[키] 접근 해당 HashTable의 키로 저장되어 있는 값에 접근 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
//키, 값 형태로 아이템 추가
ht["apple"] = "사과";
ht["banana"] = "바나나";
ht["orange"] = "오렌지";
//HashTable에 저장된 키에 해당하는 값 출력
Console.WriteLine(ht["apple"]);
Console.WriteLine(ht["banana"]);
Console.WriteLine(ht["orange"]);
}
Output
1
2
3
사과
바나나
오렌지
Queue
작동방식
FIFO(First In First Out) 방식의 개체 컬렉션
먼저 입력된 값이 먼저 출력되는 구조
메시지를 순차적으로 저장 후, 순차적으로 처리하려고하는 메시지 큐에서 사용
속성 정보 Enqueue(값) 저장(추가) Queue의 끝에 데이터를 추가함 Dequeue() 꺼내오기(불러오기, 삭제) 맨 앞의 데이터를 꺼내오고,
값을 Queue에서 삭제함Clear() 삭제 Queue에 저장된 모든 정보들을 삭제 Count 정보 현재 저장된 데이터의 총 개수를 반환함 Contains(값) 정보 Queue 내부에 해당 값이 있는지 조회함
값이 존재하면 True
값이 존재하지 않으면 FalsePeek() 접근 맨 앞에 있는 데이터를 확인함 예시
1 2 3 4 5 6 7 8 9 10 11
static void Main(string[] args) { //Queue Queue queue = new Queue(); queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); foreach (var item in queue) Console.WriteLine(item); }
Output
1 2 3
1 2 3
Stack
LIFO(Last In First Out) 방식의 개체 컬렉션
Queue와는 반대의 방식으로 작동됨
먼저 입력된 데이터가 마지막에 출력 됨
상자를 쌓은 후, 제일 위에 있는 상자부터 옮기는 경우가 예시
작동방식
| 속성 | 정보 | 내용 |
|---|---|---|
| Push(값) | 저장(추가) | Stack의 끝에 데이터를 추가 |
| Pop() | 꺼내오기(불러오기, 삭제) | 맨 뒤에 있는 데이터를 꺼내오고, Stack에서 삭제함 |
| Clear() | 삭제 | 저장된 모든 정보들을 삭제함 |
| Count() | 정보 | 현재 저장된 데이터의 총 개수를 조회함 |
| Contains(값) | 정보 | Stack안에 해당 값이 있는지 조회함 값이 존재할 경우 true 값이 없을 경우 false |
| Peek() | 접근 | 맨 앞에 있는 데이터를 확인함 |
예제
static void Main(string[] args)
{
//Stack
Stack stack = new Stack();
stack.Push(1); //값 추가
stack.Push(2);
stack.Push(3);
while(stack.Count > 0) //스택에서 아이템 제거
Console.WriteLine(stack.Pop());
}
Output
1
2
3
3
2
1


