HOWTO · Csharp

C#의 사전 대 해시 테이블

이 가이드에서는 C#에서 Dictionary와 Hashtable의 차이점에 대해 설명합니다. 어느 것을 선호해야 합니까?

이 가이드에서는 C#에서 DictionaryHashtable의 차이점에 대해 설명합니다.

이러한 컬렉션 중 어느 것이 더 좋고 선호되는지 이해하려면 기본 요소를 이해해야 합니다. 따라서 이 두 컬렉션과 관련된 구문, 특성, 기능 및 메서드를 살펴보겠습니다.

C#에서 작업할 때 어떤 것을 선호합니까? 어떤게 더 좋아?

이 모든 질문은 아래에서 답변될 것입니다. 뛰어들자!

C# 사전

사전은 일반 컬렉션입니다. 데이터를 키-값 쌍으로 저장하며 이 컬렉션에는 특별한 순서가 없습니다.

Dictionary의 구문은 다음과 같습니다.

Dictionary<TKey, TValue>

데이터 값을 키와 함께 전달합니다. 사전의 특징을 살펴보겠습니다.

C# 사전의 특징

  1. 키-값 쌍을 저장합니다.
  2. 네임스페이스는 System.Collections.Generic입니다.
  3. Dictionary의 키는 null이 아니어야 하며 고유해야 합니다.
  4. 그러나 값은 null일 수 있으며 중복될 수 있습니다.
  5. 예를 들어 myDictionary[key]와 같은 해당 키를 통해 데이터 값에 액세스할 수 있습니다.
  6. 모든 요소는 KeyValuePair<TKey, TValue>로 간주됩니다.

C#에서 사전 만들기

값 유형과 저장할 수 있는 해당 키를 전달하여 C#에서 사전을 만들 수 있습니다. Dictionary를 만드는 방법을 보려면 다음 코드를 보십시오.

IDictionary<int, string> rollno_names = new Dictionary<int, string>();
rollno_names.Add(1, "Ali");  // adding a key/value using the Add() method
rollno_names.Add(2, "Haider");
rollno_names.Add(3, "Saad");

// The following throws runtime exception: key already added.
// rollno_names.Add(3, "Rafay");

foreach (KeyValuePair<int, string> i in rollno_names)
  Console.WriteLine("Key: {0}, Value: {1}", i.Key, i.Value);

// creating a dictionary using collection-initializer syntax
var countries = new Dictionary<string, string>() {
  { "UK", "United Kingdom" }, { "USA", "United States of America" }, { "PK", "Pakistan" }
};

foreach (var j in countries) Console.WriteLine("Key: {0}, Value: {1}", j.Key, j.Value);

위의 코드에서 rollno_names는 다음과 같이 int를 키 데이터 유형으로, string을 값 데이터 유형으로 사용하는 Dictionary입니다.

Dictionary<int, string>

이 특정 Dictionary는 int 키와 문자열 값을 저장할 수 있습니다. 두 번째 Dictionary는 컬렉션 이니셜라이저가 만든 국가입니다.

키와 값은 모두 문자열 데이터 유형입니다. 키-값을 복제하고 null로 만들려고 하면 런타임 예외가 발생합니다.

C#의 사전 요소에 액세스

인덱서를 사용하여 Dictionary 요소에 액세스할 수 있습니다. 해당 값에 액세스하려면 각 키를 지정해야 합니다.

‘ElementAt()‘는 키-값 쌍을 가져오는 또 다른 접근 방식입니다. 다음 코드를 살펴보십시오.

var countries = new Dictionary<string, string>() {
  { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" }
};

Console.WriteLine(countries["UK"]);   // prints value of UK key
Console.WriteLine(countries["USA"]);  // prints value of USA key
// Console.WriteLine(countries["France"]); // runtime exception: key does not exist

// use ContainsKey() to check for the unknown key
if (countries.ContainsKey("France")) {
  Console.WriteLine(countries["France"]);
}

// use TryGetValue() to get a value of the unknown key
string result;

if (countries.TryGetValue("France", out result)) {
  Console.WriteLine(result);
}

// use ElementAt() to retrieve the key-value pair using the index
for (int i = 0; i < countries.Count; i++) {
  Console.WriteLine("Key: {0}, Value: {1}", countries.ElementAt(i).Key,
                    countries.ElementAt(i).Value);
}

위의 코드에서 France를 포함하는 키-값 쌍이 없음을 알 수 있습니다. 따라서 위의 코드는 런타임 예외를 제공합니다.

C#에서 사전 요소 업데이트

인덱서에서 키를 지정하여 키 값을 변경/업데이트할 수 있습니다. Dictionary에서 키를 찾을 수 없으면 KeyNotFoundException 예외가 발생합니다. 따라서 알 수 없는 키에 액세스하기 전에 ContainsKey() 함수를 사용하십시오.

다음 코드를 살펴보십시오.

var countries = new Dictionary<string, string>() { { "UK", "London, Manchester, Birmingham" },
                                                   { "USA", "Chicago, New York, Washington" },
                                                   { "PK", "Pakistan" } };

countries["UK"] = "Europe";    // update value of UK key
countries["USA"] = "America";  // update value of USA key
// countries["France"] = "Western Europe"; //throws run-time exception: KeyNotFoundException

if (countries.ContainsKey("France")) {
  countries["France"] = "Western Europe";
}

C#에서 사전 요소 제거

Dictionary에 이미 존재하는 키-값 쌍은 Remove() 메서드를 사용하여 제거됩니다. 모든 Dictionary 요소는 Clear() 메서드를 사용하여 제거됩니다.

var countries = new Dictionary<string, string>() {
  { "UK", "UnitedKingdom" }, { "USA", "United state of America" }, { "PK", "Pakistan" }
};

countries.Remove("UK");  // removes UK
// countries.Remove("France"); //throws run-time exception: KeyNotFoundException

if (countries.ContainsKey("France")) {  // check key before removing it
  countries.Remove("France");
}

countries.Clear();

C#의 해시 테이블

Dictionary와 달리 Hashtable은 일반 컬렉션이 아닙니다. 또한 키-값 쌍을 저장합니다.

각 키에 대한 해시 코드를 계산하고 별도의 내부 버킷에 저장하여 값에 액세스할 때 제공된 키의 해시 코드를 일치시켜 조회를 개선합니다. Hashtable의 몇 가지 특징을 살펴보십시오.

C#에서 Hashtable의 특성

  1. 키-값 쌍은 Hashtables에 보관됩니다.
  2. SystemCollection 네임스페이스에 속합니다.
  3. IDictionary 인터페이스가 구현됩니다.
  4. 키는 null일 수 없으며 고유해야 합니다.
  5. 값이 중복되거나 null일 수 있습니다.
  6. 값은 Hashtable[key]와 같이 인덱서에 관련 키를 제공하여 얻을 수 있습니다.
  7. DictionaryEntry 개체는 요소를 저장하는 데 사용됩니다.

C#에서 해시 테이블 만들기

Hashtable 생성을 이해하려면 다음 자체 설명 코드를 참조하십시오.

`Hashtable` rollno_names = new `Hashtable`();
rollno_names.Add(1, "Ali");  // adding a key/value using the Add() method
rollno_names.Add(2, "Haider");
rollno_names.Add(3, "Saad");

// The following throws runtime exception: key already added.
// rollno_names.Add(3, "Rafay");

foreach (DictionaryEntry i in rollno_names)
  Console.WriteLine("Key: {0}, Value: {1}", i.Key, i.Value);

// creating a `Hashtable` using collection-initializer syntax
var countries = new `Hashtable`() {
  { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" }
};

foreach (DictionaryEntry j in countries) Console.WriteLine("Key: {0}, Value: {1}", j.Key, j.Value);

Dictionary처럼 Hashtable을 만들 수 있습니다. 유일한 차이점은 일반이 아니므로 키의 데이터 유형과 해당 값을 지정할 필요가 없다는 것입니다.

C#의 해시 테이블에 사전 추가

Dictionary의 개체를 생성할 수 있으며 Hashtable을 생성하는 동안 해당 개체를 전달하기만 하면 Hashtable 내부에 Dictionary 키-값 쌍을 추가할 수 있습니다.

C#에서 해시 테이블 업데이트

인덱서에 키를 입력하면 Hashtable에서 기존 키의 값을 검색할 수 있습니다. Hashtable은 일반 컬렉션이 아니므로(키와 값 모두에 대한 데이터 유형이 없음을 의미), 값을 가져올 때 문자열로 유형 캐스팅해야 합니다.

다음 코드를 살펴보십시오.

// creating a Hashtable using collection-initializer syntax
var countries = new Hashtable() {
  { { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" } };

string countrynameUK = (string)countries["UK"];    // cast to string
string countrynameUSA = (string)countries["USA"];  // cast to string

Console.WriteLine(countrynameUK);
Console.WriteLine(countrynameUSA);

countries["UK"] = "Euorpe";    // update value of UK key
countries["USA"] = "America";  // update value of USA key

if (!countries.ContainsKey("France")) {
  countries["France"] = "Western Euorpe";
}

C#의 해시 테이블에서 요소 제거

Hashtable의 주어진 키-값 쌍은 Remove() 메소드를 사용하여 제거됩니다. 제공된 키가 Hashtable에 없으면 KeyNotfoundException 예외가 발생합니다. 따라서 키를 제거하기 전에 ContainsKey() 메서드를 사용하여 이미 존재하는지 확인하십시오.

Clear() 함수를 사용하여 한 번에 모든 항목을 제거합니다.

var countries = new Hashtable() {
  { "UK", "UnitedKingdom" }, { "USA", "United State of America" }, { "PK", "Pakistan" }
};

countries.Remove("UK");  // removes UK
// countries.Remove("France"); //throws run-time exception: KeyNotFoundException

if (countries.ContainsKey("France")) {  // check key before removing it
  countries.Remove("France");
}

countries.Clear();  // removes all elements

C#의 사전 대 Hashtable

Dictionary Hashtable
존재하지 않는 키를 찾으려고 하면 반환되거나 예외가 발생합니다. 존재하지 않는 키를 찾으려고 하면 null을 반환합니다.
boxing과 unboxing이 없기 때문에 Hashtable보다 빠릅니다. boxing 및 unboxing이 필요하기 때문에 Dictionary보다 더 오래 걸립니다.
스레드 안전성은 공용 정적 멤버에만 사용할 수 있습니다. Hashtable의 멤버는 모두 스레드로부터 안전합니다.
Dictionary는 일반 유형이므로 모든 데이터 유형을 함께 사용할 수 있습니다(생성할 때 키와 값 모두에 대한 데이터 유형을 지정해야 함). 제네릭 유형이 아닙니다.
강력한 형식의 키와 값을 사용하는 Hashtable 구현을 Dictionary라고 합니다. Hashtables는 유연한 유형의 데이터 구조이므로 모든 키 및 값 유형을 추가할 수 있습니다.

이러한 사실을 바탕으로 해시테이블보다 사전이 선호된다고 말할 수 있습니다. 임의의 항목을 Dictionary<TKey, TValue>에 삽입할 수 있고 가져온 값을 캐스팅할 필요가 없기 때문에 유형 안전성을 얻을 수 있습니다.