유니티에서 Dictionary<TKey, TSet>는 System.Collections.Generic 네임스페이스에 있는 제네릭 클래스이며 키-값 쌍으로 데이터를 저장하고 관리하는 데 사용된다
해시 테이블 기반의 자료구조라 Key를 사용하여 Value를 효율적으로 검색, 추가, 삭제할 수 있다
이 타입은 HashTable 타입과 유사하지만 해쉬 테이블 자료형의 경우 비제네릭이라 자료형을 명시하지 않아 박싱/언박싱이 필요하므로 성능면에서 딕셔너리가 우월하므로 가급적 딕셔너리를 사용하자
딕셔너리는 해시 테이블 기반의 자료 구조로, 버킷이라는 배열로 구성되며 하나 이상의 키-값 데이터가 저장될 수 있다. 키를 받으면 해시 함수를 사용해 키를 해시 코드로 변경하고 이렇게 나온 해시 코드를 버킷 배열의 인덱스로 사용해 데이터를 사용하고 검색한다(모든 자료형에는 GetHashCode라는 함수가 있음)
해시 충돌을 방지하기 위해 Chaining 또는 Open Addressing 등의 기법을 사용할 수 있음
선언할 때 키의 자료형, 값의 자료형을 명시해주고 다른 자료구조와 비슷하게 선언한다
// 선언
public Dictionary<int, string> idCards;
// 기본 생성자로 초기화
idCards = new Dictionary<int, string>();
// 초기 용량을 지정해서 초기화 -> 대량의 데이터 예상 시 유용
// 초기 용량을 지정하면 해시 충돌의 확률을 줄이고 데이터가 추가될 때 배열이 가득차면 새로운 배열을 할당하는 과정을 줄일 수 있어 성능을 최적화할 수 있음
idCards = new Dictionary<int, string>(100);
// 초기 데이터 지정(1번째)
idCards = new Dictionary<int, string>
{
{1, "황성빈"},
{2, "윤동희"},
{3, "고승민"}
}
// 2번째 방법
idCards = new Dictionary<int, string>
{
[1] = "황성빈",
[2] = "윤동희",
[3] = "고승민"
}
// 기존 컬렉션 복사
// 딕셔너리 타입이나 IDictionary 타입으로 복사가 할 수 있음
// Enumerable로 생성
// LINQ를 사용하여 `IEnumerable<KeyValuePair<TKey, TValue>>`를 딕셔너리로 변환할 수 있음
딕셔너리에 키-값 쌍을 추가한다. 이미 존재하는 키를 추가하려고 하면 예외가 발생함
idCards.Add(3, "레이예스"); // O
idCards.Add(0, "이대호"); // X
예외가 발생하지 않게 하려면 TryAdd 함수를 사용하자
key와 일치하는 키가 딕셔너리에 존재하는 지 확인한다. bool 값 반환
idCards.ContainsKey(0);
value와 일치하는 값이 딕셔너리에 존재하는 지 확인한다. bool 값 반환
idCards.ContainsKey(0);
지정된 키를 가진 키-값 쌍을 딕셔너리에서 제거한다. 제거에 성공하면 true, 실패하면 false 반환
idCards.Remove(2);
딕셔너리의 모든 키-값 쌍을 제거한다
딕셔너리에 저장되어 있는 키-값 쌍의 개수를 반환한다
딕셔너리에 있는 모든 키를 가져오는 프로퍼티
ICollection<int> keys = idCards.Keys;
foreach(int key in keys)
{
Debug.Log(key);
}
// 0 1 2 3
딕셔너리에 있는 모든 값을 가져오는 프로퍼티
ICollection<string> values = idCards.Values;
foreach(string value in values)
{
Debug.Log(value);
}
// 황성빈 윤동희 고승민 레이예스
딕셔너리[index]를 하게 되면 키에 맞는 값을 참조할 수 있다
[]를 사용해 키를 통해 값에 접근하고 수정할 수 있다SortedDictionary나 OrderedDictionary를 사용하는 것이 좋음SortedDictionary, 이름에서 유추할 수 있듯이 정렬된 Dictionary 자료형이다. Dictionary와 똑같이 키-값 쌍 데이터를 저장하고 관리하며 제공하는 함수들도 비슷한 편이다
하지만 Dictionary는 해시 테이블 기반으로 구현되어 있는 반면, SortedDictionary는 데이터를 정렬된 순서대로 유지해야 하기에 이진 탐색 트리(레드-블랙 트리) 기반으로 구현되어 있어 키를 자동으로 정렬한다
기본적으로 Key 자료형의 정렬 순서(예. int면 오름차순)로 정렬되지만 커스텀 정렬자를 통해 사용자 입맛대로 정렬할 수 있다
public Dictionary<int, string> idCards;
public SortedDictionary<int, string> sortedIDCards;
idCards = new Dictionary<int, string>()
{
[0] = "황성빈",
[2] = "고승민",
[1] = "윤동희"
};
sortedIDCards = new SortedDictionary<int, string>()
{
[0] = "황성빈",
[2] = "고승민",
[1] = "윤동희"
};
// 출력해보면
// 황성빈 고승민 윤동희
// 황성빈 윤동희 고승민
// 자동으로 int형 key값의 오름차순에 따라 정렬되어 저장된다
함수는 Dictionary에서 제공하는 것과 매우 비슷하므로 패스
Dictionary와 SortedDictionary를 비교해보자
따라서 키의 순서가 중요하지 않고 빠른 검색, 삽입, 삭제가 필요한 경우에는 Dictionary
키가 정렬된 상태로 유지되어야 하며 범위 검색이 필요한 경우에는 SortedDictionary를 사용하자