HOWTO · Csharp
C# での辞書とハッシュテーブル
このガイドでは、C# での辞書とハッシュテーブルの違いについて説明します。どちらがいいですか?
このページの内容
このガイドでは、C# の辞書と Hashtable の違いについて説明します。
これらのコレクションのどれがより良く、好まれているかを理解するには、それらの基本を理解する必要があります。それでは、これら 2つのコレクションに関連する構文、特性、機能、およびメソッドについて見ていきましょう。
C# で作業する場合、どちらを選択する必要がありますか?どちらが良いですか?
これらの質問はすべて以下で回答されます。飛び込みましょう!
C# の辞書
辞書は一般的なコレクションです。データはキーと値のペアで格納され、このコレクションには特定の順序はありません。
辞書の構文は次のとおりです。
Dictionary<TKey, TValue>
データ値とそのキーを渡します。辞書の特徴を見ていきましょう。
C# の辞書の特徴
- キーと値のペアを格納します。
- その名前空間は
System.Collections.Genericです。 辞書のキーは null であってはならず、一意である必要があります。- ただし、値は null で重複している可能性があります。
- 対応するキー(
myDictionary[key]など)を使用してデータ値にアクセスできます。 - すべての要素は
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# のハッシュテーブルの特徴
- キーと値のペアは
Hashtableに保持されます。 - 名前空間
SystemCollectionに属しています。 IDictionaryインターフェースが実装されています。- キーはヌルにすることはできず、区別する必要があります。
- 値が重複しているか null である可能性があります。
- 値は、
Hashtable[key]のように、インデクサーに関連するキーを提供することで取得できます。 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> に任意のランダムなアイテムを挿入でき、取り出した値をキャストする必要がないため、型の安全性が得られます。