C#のハッシュテーブルとは?Hashtableの使い方とDictionaryとの違いを初心者向けに解説
はじめに
C#でデータを管理するとき、「キーを指定して値を取り出したい」という場面はよくあります。たとえば、社員番号から社員名を取得したり、商品コードから価格を取得したり、ユーザーIDからユーザー情報を取得したりするケースです。
このような処理で使われる代表的な仕組みが、ハッシュテーブルです。C#では、古くからHashtableクラスが用意されており、キーと値のペアでデータを管理できます。
ただし、現在のC#開発ではHashtableよりもDictionary<TKey, TValue>が使われることが一般的です。そのため、初心者の方は「Hashtableとは何か」「Dictionaryと何が違うのか」「今から覚えるならどちらを使うべきか」で迷うことも多いでしょう。
この記事では、C#のハッシュテーブルの基本から、Hashtableの使い方、Dictionaryとの違い、実際の使い分けまで初心者向けにわかりやすく解説します。
1. C#のハッシュテーブルとは?
C#のハッシュテーブルとは、キーと値をセットで管理するためのデータ構造です。キーを使って目的の値を素早く取り出せるため、検索処理が多いプログラムでよく使われます。
たとえば、次のようなデータを考えてみましょう。
C#"apple" → "りんご"
"orange" → "みかん"
"banana" → "バナナ"
この場合、"apple"がキー、"りんご"が値です。キーを指定すると、それに対応する値を取得できます。
C#appleを指定する → りんごが取得できる
このように、C#のハッシュテーブルは「名前を指定してデータを取り出す箱」のようなものだと考えると理解しやすいです。
1-1. ハッシュテーブルの基本的な仕組み
ハッシュテーブルでは、キーからハッシュ値と呼ばれる数値を計算し、その数値をもとにデータの格納場所を決めます。
たとえば、"apple"というキーがあった場合、その文字列から内部的にハッシュ値が計算されます。そして、そのハッシュ値を使って、値を保存する場所を決定します。
つまり、ハッシュテーブルは次のような流れで動きます。
C#キー → ハッシュ値を計算 → 保存場所を決定 → 値を格納・取得
この仕組みによって、すべてのデータを先頭から順番に探す必要がなくなります。そのため、ハッシュテーブルは多くのデータの中から目的の値を高速に検索できます。
1-2. キーと値のペアでデータを管理するとは
ハッシュテーブルでは、データを単体で保存するのではなく、キーと値のペアとして保存します。
たとえば、学生の点数を管理する場合、次のように考えられます。
C#"田中" → 85
"佐藤" → 92
"鈴木" → 78
この場合、名前がキー、点数が値です。"佐藤"というキーを指定すれば、92という値を取得できます。
C#のHashtableでは、このようなキーと値の組み合わせを自由に追加できます。
C#Hashtable scores = new Hashtable();
scores.Add("田中", 85);
scores.Add("佐藤", 92);
scores.Add("鈴木", 78);
キーを使って値を取り出せるため、「何番目のデータか」を意識せずに扱えるのが特徴です。
1-3. 配列やリストとの違い
配列やリストは、基本的にインデックス番号を使ってデータを管理します。
C#string[] fruits = { "りんご", "みかん", "バナナ" };
Console.WriteLine(fruits[0]); // りんご
この場合、0番目、1番目、2番目という位置を指定してデータを取得します。
一方、ハッシュテーブルではキーを指定して値を取得します。
C#Hashtable fruits = new Hashtable();
fruits.Add("apple", "りんご");
fruits.Add("orange", "みかん");
fruits.Add("banana", "バナナ");
Console.WriteLine(fruits["apple"]); // りんご
配列やリストは「順番で管理する」のに対して、ハッシュテーブルは「名前やIDなどのキーで管理する」と考えるとわかりやすいです。
データを順番に並べたい場合は配列やリストが向いています。キーを使って素早く値を取り出したい場合は、ハッシュテーブルやDictionaryが向いています。
1-4. ハッシュテーブルが高速に検索できる理由
ハッシュテーブルが高速に検索できる理由は、キーから保存場所を計算できるためです。
リストの場合、目的のデータを探すには先頭から順番に確認する必要があります。データが少なければ問題ありませんが、件数が増えるほど検索に時間がかかります。
一方、ハッシュテーブルではキーからハッシュ値を計算し、目的のデータがある場所を直接探しに行きます。そのため、大量のデータがあっても効率よく値を取得できます。
ただし、常に完全に一瞬で取得できるわけではありません。異なるキーから同じような保存場所が計算されることがあり、これを衝突と呼びます。ハッシュテーブルは衝突を処理する仕組みを持っていますが、衝突が多くなるとパフォーマンスに影響することがあります。
それでも一般的な使い方では、ハッシュテーブルは非常に高速な検索が期待できるデータ構造です。
2. C#で使えるHashtableとは
C#でハッシュテーブルを扱う代表的なクラスのひとつがHashtableです。Hashtableは、キーと値をobject型として管理するコレクションクラスです。
現在ではDictionary<TKey, TValue>がよく使われますが、古いコードや既存システムではHashtableを見かけることがあります。
2-1. Hashtableクラスの概要
Hashtableは、キーと値のペアを保存するためのクラスです。キーを指定して値を追加したり、取得したり、削除したりできます。
基本的なイメージは次のとおりです。
C#Hashtable table = new Hashtable();
table.Add("id", 100);
table.Add("name", "山田太郎");
table.Add("age", 30);
この例では、"id"、"name"、"age"がキーで、100、"山田太郎"、30が値です。
値を取得するときは、キーを指定します。
C#Console.WriteLine(table["name"]); // 山田太郎
配列のように番号でアクセスするのではなく、意味のあるキーを使ってアクセスできる点が特徴です。
2-2. Hashtableを使うために必要な名前空間
Hashtableを使うには、System.Collections名前空間を読み込む必要があります。
C#using System.Collections;
完全なサンプルは次のようになります。
C#using System;
using System.Collections;
class Program
{
static void Main()
{
Hashtable table = new Hashtable();
table.Add("name", "山田太郎");
table.Add("age", 30);
Console.WriteLine(table["name"]);
Console.WriteLine(table["age"]);
}
}
HashtableはSystem.Collectionsに含まれる非ジェネリックコレクションです。
2-3. Hashtableに格納できるデータ型
Hashtableには、さまざまな型のデータを格納できます。キーも値もobject型として扱われるため、文字列、数値、真偽値などを混在させることができます。
C#Hashtable table = new Hashtable();
table.Add("name", "佐藤");
table.Add("age", 25);
table.Add("isMember", true);
このように、異なる型の値を同じHashtableに入れることができます。
ただし、これは便利な反面、注意も必要です。取り出した値はobject型として扱われるため、必要に応じて型変換が必要になります。
C#int age = (int)table["age"];
型を間違えると実行時エラーになる可能性があるため、初心者の方は注意しましょう。
2-4. Hashtableが古くから使われている理由
Hashtableは、C#の初期から使われてきたコレクションクラスです。ジェネリックが一般的になる前は、キーと値のペアを管理する方法としてよく利用されていました。
そのため、古いC#のサンプルコードや長く運用されている業務システムでは、今でもHashtableが使われていることがあります。
しかし、現在のC#では型安全で使いやすいDictionary<TKey, TValue>があるため、新しくコードを書く場合はDictionaryを使うことが多いです。
つまり、Hashtableは「今でも知っておくべきだが、新規開発では積極的に選ばれることは少ないクラス」と考えるとよいでしょう。
3. Hashtableの基本的な使い方
ここからは、C#でHashtableを使う基本的な方法を見ていきます。宣言、追加、取得、更新、削除、一覧表示まで順番に確認しましょう。
3-1. Hashtableの宣言と初期化
Hashtableを使うには、まずインスタンスを作成します。
C#Hashtable table = new Hashtable();
この時点では、中身は空です。ここにAddメソッドなどを使って要素を追加していきます。
C#using System;
using System.Collections;
class Program
{
static void Main()
{
Hashtable table = new Hashtable();
}
}
Hashtableを使う場合は、先ほど説明したようにusing System.Collections;を忘れないようにしましょう。
3-2. Addメソッドで要素を追加する方法
Hashtableに要素を追加するには、Addメソッドを使います。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
table.Add("banana", "バナナ");
Addメソッドの第1引数にはキー、第2引数には値を指定します。
C#table.Add(キー, 値);
たとえば、商品コードと商品名を管理する場合は次のように書けます。
C#Hashtable products = new Hashtable();
products.Add("A001", "ノートパソコン");
products.Add("A002", "マウス");
products.Add("A003", "キーボード");
キーをわかりやすく設定しておくと、後から値を取得しやすくなります。
3-3. キーを指定して値を取得する方法
Hashtableから値を取得するには、角括弧[]にキーを指定します。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
Console.WriteLine(table["apple"]); // りんご
Console.WriteLine(table["orange"]); // みかん
このように、キーを指定するだけで対応する値を取得できます。
ただし、戻り値はobject型です。文字列として扱いたい場合は、明示的に型変換することがあります。
C#string fruit = (string)table["apple"];
Console.WriteLine(fruit);
数値の場合も同じです。
C#Hashtable scores = new Hashtable();
scores.Add("田中", 80);
int score = (int)scores["田中"];
Console.WriteLine(score);
3-4. 値を更新する方法
Hashtableに登録済みの値を更新するには、キーを指定して新しい値を代入します。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table["apple"] = "リンゴ";
Console.WriteLine(table["apple"]); // リンゴ
すでに存在するキーに対して代入すると、値が上書きされます。
また、存在しないキーに対して代入した場合は、新しい要素として追加されます。
C#table["grape"] = "ぶどう";
Console.WriteLine(table["grape"]); // ぶどう
Addメソッドは同じキーがすでに存在するとエラーになりますが、table["key"] = valueの形では追加または更新ができます。
3-5. Removeメソッドで要素を削除する方法
Hashtableから要素を削除するには、Removeメソッドを使います。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
table.Remove("apple");
Console.WriteLine(table["apple"]); // 何も表示されない
Removeメソッドには、削除したい要素のキーを指定します。
C#table.Remove(キー);
存在しないキーを指定してもエラーにはなりません。削除対象がなければ、何も起こらずに処理が続きます。
3-6. foreachでHashtableの中身を一覧表示する方法
Hashtableの中身を一覧表示するには、foreach文を使います。
Hashtableの各要素はDictionaryEntryとして取り出せます。
C#using System;
using System.Collections;
class Program
{
static void Main()
{
Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
table.Add("banana", "バナナ");
foreach (DictionaryEntry item in table)
{
Console.WriteLine(item.Key + " : " + item.Value);
}
}
}
実行すると、キーと値のペアが表示されます。
ただし、表示される順番は追加した順番とは限りません。Hashtableではデータの順序は保証されないため、順番に意味を持たせたい場合は注意が必要です。
4. Hashtableでよく使うメソッドとプロパティ
Hashtableには、要素の追加や削除以外にも便利なメソッドやプロパティがあります。ここでは、よく使うものを紹介します。
4-1. Countで要素数を取得する
Countプロパティを使うと、Hashtableに格納されている要素数を取得できます。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
Console.WriteLine(table.Count); // 2
データが何件登録されているか確認したいときに便利です。
4-2. ContainsKeyでキーの存在を確認する
指定したキーが存在するか確認するには、ContainsKeyメソッドを使います。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
if (table.ContainsKey("apple"))
{
Console.WriteLine("appleキーは存在します");
}
存在しないキーを使って値を取得すると、期待した値が得られないことがあります。そのため、値を取得する前にContainsKeyで確認すると安全です。
C#if (table.ContainsKey("orange"))
{
Console.WriteLine(table["orange"]);
}
else
{
Console.WriteLine("orangeキーは存在しません");
}
4-3. ContainsValueで値の存在を確認する
指定した値が存在するか確認するには、ContainsValueメソッドを使います。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
if (table.ContainsValue("りんご"))
{
Console.WriteLine("りんごは存在します");
}
ContainsKeyはキーを調べるメソッド、ContainsValueは値を調べるメソッドです。
ただし、ハッシュテーブルはキーによる検索を得意とするデータ構造です。値の検索はキーの検索ほど効率的ではないため、大量データで頻繁に値を検索する用途には注意が必要です。
4-4. Clearで全要素を削除する
Hashtableのすべての要素を削除するには、Clearメソッドを使います。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
table.Clear();
Console.WriteLine(table.Count); // 0
Clearを実行すると、中身がすべて削除されます。特定の要素だけ削除したい場合はRemove、全削除したい場合はClearを使いましょう。
4-5. KeysとValuesでキー・値の一覧を取得する
Keysプロパティを使うと、Hashtableに登録されているキーの一覧を取得できます。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("orange", "みかん");
foreach (object key in table.Keys)
{
Console.WriteLine(key);
}
一方、Valuesプロパティを使うと、値の一覧を取得できます。
C#foreach (object value in table.Values)
{
Console.WriteLine(value);
}
キーだけを一覧表示したい場合はKeys、値だけを一覧表示したい場合はValuesを使うと便利です。
5. Hashtableを使うときの注意点
Hashtableは便利なクラスですが、使うときにはいくつか注意点があります。特に初心者の方は、キーの重複や型変換、順序の扱いでつまずきやすいです。
5-1. キーの重複はできない
Hashtableでは、同じキーを複数登録することはできません。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
table.Add("apple", "リンゴ"); // エラー
同じキーをAddメソッドで追加しようとすると、例外が発生します。
値を更新したい場合は、Addではなく代入を使います。
C#table["apple"] = "リンゴ";
キーがすでに存在するか不安な場合は、ContainsKeyで確認してから追加すると安全です。
C#if (!table.ContainsKey("apple"))
{
table.Add("apple", "りんご");
}
5-2. 存在しないキーを指定した場合の挙動
存在しないキーを指定して値を取得すると、nullが返されます。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
Console.WriteLine(table["orange"]); // null
存在しないキーを指定しても、すぐにエラーになるわけではありません。しかし、その結果を文字列や数値として扱おうとすると問題が起きることがあります。
たとえば、次のようなコードでは注意が必要です。
C#string value = (string)table["orange"];
存在しないキーの場合、valueにはnullが入ります。想定外のnullを避けるためにも、ContainsKeyで存在確認をしてから取得するのが安全です。
5-3. 型変換が必要になるケース
Hashtableでは、キーも値もobject型として扱われます。そのため、値を取り出して特定の型として使う場合は型変換が必要です。
C#Hashtable table = new Hashtable();
table.Add("age", 30);
int age = (int)table["age"];
このように、整数として使いたい場合は(int)でキャストします。
ただし、型を間違えるとエラーになります。
C#string age = (string)table["age"]; // エラー
table["age"]に入っているのは整数なので、文字列としてキャストすることはできません。
このような型の間違いが実行するまでわかりにくい点は、Hashtableの大きな注意点です。
5-4. nullを扱うときの注意点
Hashtableでは、値としてnullを登録できます。
C#Hashtable table = new Hashtable();
table.Add("name", null);
一方で、存在しないキーを指定した場合もnullが返されます。
C#Console.WriteLine(table["unknown"]); // null
つまり、値としてnullが登録されているのか、キー自体が存在しないのかを、取得結果だけで判断するのは難しい場合があります。
そのため、キーが存在するかどうかを判断したい場合は、必ずContainsKeyを使いましょう。
C#if (table.ContainsKey("name"))
{
Console.WriteLine("nameキーは存在します");
}
また、Hashtableではキーにnullを指定することはできません。キーはデータを探すための重要な情報なので、必ず有効な値を指定する必要があります。
5-5. データの順序は保証されない
Hashtableでは、データの順序は保証されません。
次のように追加したとしても、
C#table.Add("first", "1番目");
table.Add("second", "2番目");
table.Add("third", "3番目");
foreachで取り出したときに、追加した順番で表示されるとは限りません。
C#foreach (DictionaryEntry item in table)
{
Console.WriteLine(item.Key + " : " + item.Value);
}
ハッシュテーブルは高速な検索を目的としたデータ構造であり、順番を管理するためのものではありません。データの順序が重要な場合は、リストや配列、または順序を扱える別のコレクションを検討しましょう。
6. HashtableとDictionaryの違い
C#でキーと値のペアを扱う場合、HashtableだけでなくDictionary<TKey, TValue>もよく使われます。むしろ現在のC#では、Dictionaryの方が一般的です。
ここでは、HashtableとDictionaryの違いをわかりやすく整理します。
6-1. HashtableとDictionaryの基本的な違い
HashtableとDictionaryは、どちらもキーと値のペアを管理するためのコレクションです。
Hashtableの例は次のとおりです。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
Console.WriteLine(table["apple"]);
Dictionaryでは、キーと値の型を指定して使います。
C#Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("apple", "りんご");
Console.WriteLine(dictionary["apple"]);
大きな違いは、Hashtableはキーと値をobject型として扱うのに対し、Dictionaryはキーと値の型を明確に指定できる点です。
6-2. 型安全性の違い
Hashtableは、さまざまな型の値を入れられます。
C#Hashtable table = new Hashtable();
table.Add("name", "山田");
table.Add("age", 30);
table.Add("isMember", true);
一見便利ですが、取り出すときに型変換が必要です。
C#int age = (int)table["age"];
型を間違えると実行時にエラーが発生します。
一方、Dictionaryでは最初に型を指定します。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 80);
scores.Add("佐藤", 90);
この場合、キーはstring、値はintだけです。間違った型の値を入れようとすると、コンパイル時にエラーになります。
C#scores.Add("鈴木", "高得点"); // エラー
このように、Dictionaryは型の間違いに早く気づけるため、安全にコードを書きやすいです。
6-3. パフォーマンスの違い
HashtableとDictionaryはどちらもハッシュテーブルの仕組みを使っているため、キーによる検索は高速です。
ただし、Hashtableはキーや値をobjectとして扱うため、値型を扱う場合にボックス化やアンボックス化が発生することがあります。
たとえば、整数をHashtableに入れる場合、内部的にはobjectとして扱われます。
C#Hashtable table = new Hashtable();
table.Add("age", 30);
int age = (int)table["age"];
一方、Dictionary<string, int>のように型を指定しておけば、余計な型変換を減らせます。
C#Dictionary<string, int> dictionary = new Dictionary<string, int>();
dictionary.Add("age", 30);
int age = dictionary["age"];
一般的には、現在のC#ではDictionaryの方が型安全でパフォーマンス面でも扱いやすい選択肢です。
6-4. コードの書きやすさの違い
Hashtableでは、値を取り出すたびに型変換が必要になることがあります。
C#int age = (int)table["age"];
string name = (string)table["name"];
データの型が増えるほど、キャストの記述が多くなり、コードが読みにくくなる場合があります。
一方、Dictionaryでは型が決まっているため、取り出した値をそのまま使えます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 80);
int score = scores["田中"];
キャストが不要なので、コードがすっきりします。また、型の間違いをコンパイル時に発見しやすいため、保守もしやすくなります。
6-5. 現在のC#開発でDictionaryが推奨される理由
現在のC#開発では、HashtableよりもDictionary<TKey, TValue>が推奨されることが多いです。
主な理由は次のとおりです。
C#・型安全に使える
・キャストが少なくコードが読みやすい
・コンパイル時に型の間違いを発見しやすい
・ジェネリックに対応している
・現代的なC#の書き方に合っている
特に初心者にとっては、型の間違いを早く発見できることが大きなメリットです。
HashtableはC#の古いコードを読むために知っておく価値がありますが、新しくコードを書く場合は基本的にDictionaryを使うとよいでしょう。
7. HashtableとDictionaryの使い分け
HashtableとDictionaryは似ていますが、現在のC#では使い分けの考え方がはっきりしています。
基本的には、新規開発ではDictionaryを使い、既存コードや古いライブラリとの互換性が必要な場合にHashtableを理解する、という考え方で問題ありません。
7-1. Hashtableを使ってもよいケース
Hashtableを使ってもよいケースとしては、古いコードや既存システムを保守する場合が挙げられます。
たとえば、昔から運用されているC#の業務アプリケーションでは、Hashtableが使われていることがあります。そのようなコードを修正する場合、無理にすべてDictionaryへ置き換えるより、既存の設計に合わせてHashtableを使う方が安全なこともあります。
また、古いライブラリやAPIがHashtableを受け取るように設計されている場合もあります。その場合は、互換性のためにHashtableを使うことがあります。
ただし、新しく自分でコードを書く場合に、あえてHashtableを選ぶ場面は多くありません。
7-2. Dictionaryを使うべきケース
新しくC#のコードを書く場合は、基本的にDictionary<TKey, TValue>を使うのがおすすめです。
たとえば、文字列のキーで点数を管理するなら次のように書けます。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
scores.Add("田中", 80);
scores.Add("佐藤", 90);
Console.WriteLine(scores["田中"]);
商品コードと商品名を管理する場合は、次のように書けます。
C#Dictionary<string, string> products = new Dictionary<string, string>();
products.Add("A001", "ノートパソコン");
products.Add("A002", "マウス");
Dictionaryは型を明確にできるため、コードの意図がわかりやすくなります。保守性や安全性を考えても、通常はDictionaryを選ぶのがよいでしょう。
7-3. 初心者はどちらを覚えるべきか
初心者が最初に覚えるべきなのは、Dictionary<TKey, TValue>です。
理由は、現在のC#開発でよく使われるのがDictionaryだからです。また、型を指定して使えるため、コードの意味を理解しやすく、エラーにも気づきやすいです。
ただし、Hashtableをまったく知らなくてよいわけではありません。古いサンプルコードや既存システムではHashtableが登場することがあります。
そのため、学習の順番としては次のように考えるとよいでしょう。
C#1. まずDictionaryをしっかり覚える
2. その後、Hashtableは古い書き方として理解する
3. 既存コードで見かけたときに読めるようにする
実務では、Dictionaryを使えることの方が重要です。
7-4. 既存コードでHashtableを見かけたときの考え方
既存コードでHashtableを見かけた場合は、まず「キーと値のペアを管理している」と理解しましょう。
次に、どのようなキーが使われているか、どのような値が入っているかを確認します。
C#Hashtable table = new Hashtable();
table.Add("UserName", "山田");
table.Add("UserAge", 30);
このようなコードでは、文字列のキーに対してユーザー情報が格納されています。
修正する場合は、型変換に注意しましょう。
C#string userName = (string)table["UserName"];
int userAge = (int)table["UserAge"];
もし大きな改修を行う場合は、Dictionaryへの置き換えを検討できることもあります。ただし、既存コードへの影響範囲が広い場合は、安易に変更すると不具合につながる可能性があります。
まずはHashtableの役割を理解し、必要に応じて慎重に対応することが大切です。
8. C#のハッシュテーブルに関するよくある疑問
最後に、C#のハッシュテーブルやHashtableに関するよくある疑問を整理します。
8-1. HashtableとHashSetの違いは?
HashtableとHashSetは名前が似ていますが、役割は異なります。
Hashtableは、キーと値のペアを管理するためのコレクションです。
C#"apple" → "りんご"
"orange" → "みかん"
一方、HashSet<T>は、重複しない値の集合を管理するためのコレクションです。
C#HashSet<string> fruits = new HashSet<string>();
fruits.Add("apple");
fruits.Add("orange");
fruits.Add("apple"); // 重複なので追加されない
つまり、キーと値のペアを扱いたい場合はHashtableやDictionary、重複しない値の一覧を扱いたい場合はHashSetを使います。
8-2. Hashtableは現在でも使われる?
Hashtableは現在でも使えますが、新規開発で積極的に使われることは少なくなっています。
現在のC#では、型安全で扱いやすいDictionary<TKey, TValue>がよく使われます。
ただし、古いシステムや古いサンプルコードではHashtableを見かけることがあります。そのため、Hashtableの基本的な使い方を知っておくと、既存コードを読むときに役立ちます。
8-3. Hashtableはジェネリックに対応している?
Hashtableはジェネリックに対応していません。
Hashtableでは、キーも値もobject型として扱われます。
C#Hashtable table = new Hashtable();
一方、Dictionaryはジェネリックに対応しています。
C#Dictionary<string, int> scores = new Dictionary<string, int>();
このように、Dictionaryではキーと値の型を指定できます。
ジェネリックに対応していることで、型安全に使える、キャストが不要になる、コードが読みやすくなるといったメリットがあります。
8-4. Dictionaryはハッシュテーブルの一種なのか?
Dictionary<TKey, TValue>は、内部的にハッシュテーブルの仕組みを利用したコレクションです。
そのため、広い意味ではDictionaryもハッシュテーブルの一種と考えられます。
ただし、C#でHashtableという場合は、System.Collections.Hashtableクラスを指すことが多いです。一方、DictionaryはSystem.Collections.Generic.Dictionary<TKey, TValue>クラスです。
つまり、どちらもキーと値のペアを高速に扱うコレクションですが、C#のクラスとしては別物です。
初心者の方は、次のように整理するとわかりやすいです。
C#Hashtable = 古くからある非ジェネリックのクラス
Dictionary = 現在よく使われるジェネリック対応のクラス
8-5. JavaScriptやJavaのハッシュテーブルとの違いは?
ハッシュテーブルという考え方自体は、C#だけでなくJavaScriptやJavaにもあります。
Javaでは、古くからHashtableクラスがあり、現在ではHashMapがよく使われます。C#のHashtableとDictionaryの関係は、JavaのHashtableとHashMapの関係に少し似ています。
JavaScriptでは、オブジェクトやMapを使ってキーと値のペアを管理できます。
JavaScriptconst map = new Map();
map.set("apple", "りんご");
console.log(map.get("apple"));
言語によってクラス名や使い方は異なりますが、「キーを指定して値を取り出す」という基本的な考え方は共通しています。
C#では、古い書き方としてHashtable、現在よく使われる書き方としてDictionary<TKey, TValue>を覚えておくとよいでしょう。
まとめ
C#のハッシュテーブルは、キーと値のペアでデータを管理し、キーを使って値を高速に取得できるデータ構造です。配列やリストが順番でデータを管理するのに対し、ハッシュテーブルは名前やIDのようなキーを使ってデータを管理します。
C#では、ハッシュテーブルを扱うクラスとしてHashtableがあります。Hashtableを使うと、キーと値を追加したり、取得したり、更新したり、削除したりできます。
C#Hashtable table = new Hashtable();
table.Add("apple", "りんご");
Console.WriteLine(table["apple"]);
ただし、Hashtableはキーも値もobject型として扱うため、型変換が必要になることがあります。また、型の間違いに実行時まで気づきにくいという注意点もあります。
現在のC#開発では、HashtableよりもDictionary<TKey, TValue>がよく使われます。
C#Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("apple", "りんご");
Console.WriteLine(dictionary["apple"]);
Dictionaryは型安全で、キャストが少なく、コードも読みやすくなります。そのため、新しくC#を学ぶ初心者は、まずDictionaryをしっかり覚えるのがおすすめです。
一方で、古いコードや既存システムではHashtableを見かけることがあります。Hashtableの基本を理解しておけば、過去のコードを読むときや保守するときに役立ちます。
C#のハッシュテーブルを理解するうえでは、Hashtableの使い方を知りつつ、実際の開発ではDictionaryを中心に使う、という考え方を持っておくとよいでしょう。

