-
컬렉션
: 동일 타입의 객체(데이터)를 여러 개 보관할 수 있는 클래스들의 모음.
: 배열을 제외한 나머지 컬렉션은 주로, 제네릭 클래스를 활용
I. 배열
: 동일한 자료형의 값들이 고정된 크기에 연속적으로 저장되는 컬렉션
1. 1차원 배열
: 동일한 데이터 유형을 가지는 데이터 요소들을 한 번에 모아서 다룰 수 있는 자료 구조
: 인덱스를 사용하여 요소에 접근 가능
: 선언된 크기만큼의 공간을 메모리에 할당받음
타입 [] 배열명 = new 타입[배열의 길이 i] ;
int[] array1 = new int[5]; // 크기가 5인 int형 배열 선언 string[] array2 = new string[3]; // 크기가 3인 string형 배열 선언 int num = 0; // 배열 초기화 /* array1[0] = 1; array1[1] = 2; array1[2] = 3; array1[3] = 4; array1[4] = 5; --> 보통은 일일히 배열에 넣지않고 규칙에 근거하여 반복문을 활용해 배열을 채운다. */ for (int i = 0; i < array1.Length; i++) { array1[i] = i+1; } num = array1[0]; // 1
!! 배열의 생성과 지정 데이터의 초기화
타입 [] 배열명 = new 타입[배열의 길이 i] (배열의 요소1, 배열의 요소 2, ... , 배열의 요소 i) ;
!! 배열의 암시적 선언
타입 [] 배열명 = {배열의 요소1, 배열의 요소 2, ... , 배열의 요소 i} ;
int[] itemPrices = { 100, 200, 300, 400, 500 }; int totalPrice = 0; for (int i = 0; i < itemPrices.Length; i++) { totalPrice += itemPrices[i]; } Console.WriteLine("총 아이템 가격: " + totalPrice + " gold");
2. 다차원 배열
: 여러 개의 배열을 하나로 묶어 놓은 2차원 이상의 배열.
: 행렬 연산과 같은 여러 차원의 데이터를 다루는데 유용하다.
타입 [ , ] 배열명 = new 타입[배열의 길이 i , 배열의 길이 j] ;
// 2차원 배열 int[,] array2D = new int[2, 3]; /* 초기화 array2D[0, 0] = 1; array2D[0, 1] = 2; array2D[0, 2] = 3; array2D[1, 0] = 4; array2D[1, 1] = 5; array2D[1, 2] = 6; */ // 마찬가지로, for문으로 배열을 생성해보면.. int array2DRow = array2D.GetLength(0); // 행의 길이 int array2DCol = array2D.GetLength(1); // 열의 길이 for (int i = 0; i < array2DRow; i++) { for (int j = 1; j < array2DCol+1; j++) { array2D[i, j-1] = i * array2DCol + j; Console.Write(array2D[i, j-1] + " "); // 출력 } Console.WriteLine(); // 출력을 위한 줄바꿈 }
>
!! 2차원 배열을 활용한 게임맵 구현
int[,] map = new int[5, 5] { { 1, 1, 1, 1, 1 }, { 1, 0, 0, 0, 1 }, { 1, 0, 1, 0, 1 }, { 1, 0, 0, 0, 1 }, { 1, 1, 1, 1, 1 } }; for (int i = 0; i < 5; i++) { for (int j = 0; j < 5; j++) { if (map[i, j] == 1) { Console.Write("■ "); } else { Console.Write("□ "); } } Console.WriteLine(); }
>
II. 리스트 (List)
: 동적 크기의 컬렉션
: 가변적인 크기를 갖는 배열
: 성능 이슈로 주로 제네릭 클래스(System.Collections.Generic)의 List<T>를 사용함.
1. 제네릭 리스트 ( List<T> )
: 지정한 타입의 데이터 형식만을 저장
: 내부적으로 배열을 사용하여 데이터를 저장하고 관리. => 인덱스를 사용한 빠른 검색 속도
: 단, 요소 추가/제거 시에 재할당과 복사가 필요할 수 있어서 추가/제거 작업시, 속도는 느리다.
List<타입> 배열명 = new List<타입>();
List<int> numbers = new List<int>(); // 빈 리스트 생성 numbers.Add(1); // 리스트에 데이터 추가 numbers.Add(2); numbers.Add(3); numbers.Remove(2); // 리스트에서 데이터 삭제 foreach(int number in numbers) // 리스트 데이터 출력 { Console.WriteLine(number); }
2. 어레이 리스트 (ArrayList)
: 모든 타입의 데이터 형식 저장 => object 형식을 사용하여 모든 데이터 처리 => 더 많은 메모리 사용량
: 내부적으로 배열을 사용하여 데이터를 저장하고 관리. => 인덱스를 사용한 빠른 검색 속도
: 제네릭 클래스에서 효율적인 작업을 위해 각 종류의 컬렉션들에 대해, .NET Framework에서 최적화되어 설계됨.
==> 저장할 데이터의 타입이 고정되지 않는다면(제네릭 리스트를 사용할 수 없다면) 사용하도록 하자.
ArrayList 리스트명 = new ArrayList();
!! 연결 리스트(linked list)
: 데이터 요소를 노드(Node)라 불리는 개별적인 단위로 나누고, 이 노드들이 연결되어 선형적인 데이터 구조흘 형성하는 자료구조.
!! 배열과 리스트
: 배열과 리스트의 차이는 고정된 크기를 갖느냐, 동적인 크기를 갖느냐의 여부이다.
:
동적인 크기를 갖는 리스트가 더 유연하므로, 배열보다 압도적으로 많이 활용할 수 있을 것 같지만, 다음의 요소를 고려한 뒤, 적재적소에 배열과 리스트를 구분하여 활용할 줄 알아야함.기존의 리스트의 단점을 제네릭클래스의 리스트에서는 보완한듯.: 크기 변화가 자주 일어나는가? 어떠한 타입의 데이터를 다루는가? 에 따라 구분하여 사용해야 할듯
1. 메모리
: 제네릭 클래스의 리스트는 크기 조절로 인해 메모리 재할당과 복사가 필요할 수 있다.
2. 데이터 접근 시간
: 배열은 데이터를 연속된 메모리 공간에 저장함. 리스트는 연속된 메모리 공간에 저장되지 않음.
: 배열은 인덱스를 사용하여 요소에 직접 접근 가능. 제네릭클래스의 리스트 또한 인덱스 사용.3. 코드 복잡도 증가.: 크기 조정과 데이터 추가, 삭제 등의 작업을 처리하는 코드를 작성할 시, 배열보다 복잡함.III. 딕셔너리 (Dictionary)
: 키(key)와 값(value)로 구성된 요소들을 저장하는 컬렉션
: 딕셔너리는 중복된 키를 가질 수 없으며, 키와 값의 쌍을 이루어 데이터를 저장한다.
: 성능 이슈로 주로 제네릭 클래스(System.Collections.Generic)의 Dictionary를 사용함.
Dictionary<타입(키), 타입(값)> 배열명 = new Dictionary<타입(키), 타입(값)>();
using System.Collections.Generic; Dictionary<string, int> skills = new Dictionary<string, int>(); // 빈 딕셔너리 생성 skills.Add("PowerStrike", 10); // 딕셔너리에 데이터 추가 skills.Add("MagicClaw", 40); skills.Add("LuckySeven", 20); skills.Remove("MagicClaw"); // 딕셔너리에서 데이터 삭제 foreach(KeyValuePair<string, int> pair in skills) // 딕셔너리 데이터 출력 { Console.WriteLine(pair.Key + ": " + pair.Value); }
>
IV. 큐 (Queue)
: 선입선출(FIFO)의 원칙으로 데이터를 저장하는 컬렉션
: ex) 네트워크 통신, 캐시(cache) 등.,,
Queue<타입> 배열명 = new Queue<타입>();
Queue<int> queue1 = new Queue<int>(); // int형 Queue 선언 // Queue에 요소 추가 queue1.Enqueue(1); queue1.Enqueue(2); queue1.Enqueue(3); // Queue에서 요소 가져오기 int value = queue1.Dequeue(); // value = 1 (가장 먼저 추가된 요소)
V. 스택 (Stack)
: 후입선출(LIFO) 원칙으로 데이터를 저장하는 컬렉션
: ex) 브라우저의 뒤로 가기 기능, Ctrl + z 기능..
Stack<타입> 스택명 = new Stack<타입>();
Stack<int> stack1 = new Stack<int>(); // int형 Stack 선언 // Stack에 요소 추가 stack1.Push(1); stack1.Push(2); stack1.Push(3); // Stack에서 요소 가져오기 int value = stack1.Pop(); // value = 3 (마지막에 추가된 요소)
VI. 해시셋 (HashSet)
: 중복 요소 없이 값을 저장하는 컬렉션.
: 고유한 값의 집합.
Hashset<타입> 해시셋명 = new Hashset<타입>();
HashSet<int> set1 = new HashSet<int>(); // int형 HashSet 선언 // HashSet에 요소 추가 set1.Add(1); set1.Add(2); set1.Add(3); // HashSet에서 요소 가져오기 foreach (int element in set1) { Console.WriteLine(element); }