C# での辞書とハッシュテーブル

Haider Ali 2023年10月12日
  1. C# の辞書
  2. C# のハッシュテーブル
  3. C# の辞書とハッシュテーブル
C# での辞書とハッシュテーブル

このガイドでは、C# の辞書Hashtable の違いについて説明します。

これらのコレクションのどれがより良く、好まれているかを理解するには、それらの基本を理解する必要があります。それでは、これら 2つのコレクションに関連する構文、特性、機能、およびメソッドについて見ていきましょう。

C# で作業する場合、どちらを選択する必要がありますか?どちらが良いですか?

これらの質問はすべて以下で回答されます。飛び込みましょう!

C# の辞書

辞書は一般的なコレクションです。データはキーと値のペアで格納され、このコレクションには特定の順序はありません。

辞書の構文は次のとおりです。

Dictionary<TKey, TValue>

データ値とそのキーを渡します。辞書の特徴を見ていきましょう。

C# の辞書の特徴

  1. キーと値のペアを格納します。
  2. その名前空間は System.Collections.Generic です。
  3. 辞書のキーは null であってはならず、一意である必要があります。
  4. ただし、値は null で重複している可能性があります。
  5. 対応するキー(myDictionary[key] など)を使用してデータ値にアクセスできます。
  6. すべての要素は KeyValuePair<TKey, TValue> と見なされます。

C# で辞書を作成する

保存できる値のタイプとそれに対応するキーを渡すことにより、C# で辞書を作成できます。次のコードを見て、辞書を作成する方法を確認してください。

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<int, string>

この特定の辞書は、int キーと文字列値を格納できます。2 番目の辞書は、コレクション初期化子によって作成された国のものです。

キーと値はどちらも文字列データ型です。Key-Value を複製して null にしようとすると、実行時例外が発生します。

C# の辞書要素にアクセスする

インデクサーを使用して、Dictionary 要素にアクセスできます。対応する値にアクセスするには、各キーを指定する必要があります。

ElementAt() は、キーと値のペアを取得するためのもう 1つのアプローチです。次のコードを見てください。

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);
}

上記のコードでは、フランスを含むキーと値のペアがないことがわかります。したがって、上記のコードは実行時例外を発生させます。

C# の辞書要素を更新する

インデクサーでキーを指定することにより、キーの値を変更/更新できます。辞書でキーが見つからない場合、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# のハッシュテーブル

辞書とは異なり、Hashtable は非ジェネリックコレクションです。また、キーと値のペアも格納します。

各キーのハッシュコードを計算し、それを個別の内部バケットに格納することで、値にアクセスするときに提供されたキーのハッシュコードを照合することにより、ルックアップを改善します。Hashtable のいくつかの特徴を見てみましょう。

C# のハッシュテーブルの特徴

  1. キーと値のペアは Hashtable に保持されます。
  2. 名前空間 SystemCollection に属しています。
  3. IDictionary インターフェースが実装されています。
  4. キーはヌルにすることはできず、区別する必要があります。
  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);

辞書と同じように 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# の辞書とハッシュテーブル

Dictionary Hashtable
存在しないキーを検出しようとすると、例外が返されるか、例外がスローされます。 存在しないキーを検出しようとすると、null が返されます。
ボクシングとアンボクシングがないため、Hashtable よりも高速です。 ボクシングとアンボクシングが必要なため、辞書よりも時間がかかります。
スレッドセーフは、パブリックスタティックメンバーでのみ使用できます。 Hashtable のメンバーはすべてスレッドセーフであり、
Dictionary はジェネリック型であるため、任意のデータ型を使用できます(作成時に、キーと値の両方のデータ型を指定する必要があります)。 ジェネリックタイプではありません。
強く型付けされたキーと値を使用した Hashtable の実装は、ディクショナリと呼ばれます。 Hashtable は柔軟に型指定されたデータ構造であるため、任意のキーと値の型を追加できます。

これらの事実に基づいて、Hashtable よりも辞書の方が好ましいと言えます。Dictionary<TKey, TValue> に任意のランダムなアイテムを挿入でき、取り出した値をキャストする必要がないため、型の安全性が得られます。

著者: Haider Ali
Haider Ali avatar Haider Ali avatar

Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.

LinkedIn

関連記事 - Csharp Dictionary