1,277


285

ほとんどのプログラミング言語では、辞書はハッシュテーブルよりも好まれています。 その理由は何ですか?

18 Answer


1,475


それが価値があるもののために、辞書はハッシュテーブルです(概念的に)。

「なぜHashtableクラスではなく、Dictionaryクラスを使うのですか」と言うのであれば、簡単な答えです。「Dictionary」はジェネリック型ですが、「Hashtable」はそうではありません。 これは `Dictionary`で型安全が得られることを意味します。ランダムなオブジェクトをそこに挿入することはできず、取り出した値をキャストする必要もないからです。

興味深いことに、.NET Frameworkの Dictionary`実装は Hashtable`に基づいています。これはソースコードのこのコメントからわかるように:

_ 汎用辞書はHashtableのソースからコピーされました _


589


  • Dictionary * <<< >>> *` Hashtable` *の違い:

  • 一般 <<< >>> 非一般

  • 自分のスレッド同期 <<< >>>が必要*スレッドセーフバージョンを提供

  • Synchronized() *メソッドを介して

  • 列挙型アイテム:* KeyValuePair * <<< >>>列挙型アイテム:

  • DictionaryEntry *

  • 新しい(> * .NET 2.0 )<<< >>>古いバージョン( .NET 1.0 *以降)

  • * System.Collections.Generic * <<< >>>には* System.Collections *にあります。

  • 存在しないキーへのリクエスト*例外をスロー* <<< >>>へのリクエスト 存在しないキー* nullを返します*

  • 潜在的に少し*値の型が速い* <<< >>> 少し遅い(必要 値型のボクシング/アンボクシング)

  • Dictionary * / *` Hashtable` *類似点:

  • 両方とも内部的には*ハッシュテーブル* ==多項目データへの高速アクセス キーに従って

  • 両方とも*不変でユニークなキー*が必要です

  • 両方のキーは独自の* GetHashCode() *メソッドを必要とします

類似 .NETコレクション(DictionaryおよびHashtableの代わりに使用する候補):

  • ConcurrentDictionary-スレッドセーフ(から安全にアクセスできます 同時に複数のスレッド)

  • HybridDictionary-最適化されたパフォーマンス(いくつかのアイテムと 多くのアイテム用)

  • OrderedDictionary-intインデックスを介して*値にアクセスできます*(順序で アイテムが追加された場所)

  • SortedDictionary - アイテム*自動的にソート*

  • StringDictionary - 強く型付けされ*文字列用に最適化された*


168


Dictionary`はジェネリッククラス( Dictionary`)なので、そのコンテンツへのアクセスは型保証されています(つまり、 Hashtable`の場合のように、 Object`からキャストする必要はありません。

比較する

var customers = new Dictionary();
...
Customer customer = customers["Ali G"];

to

var customers = new Hashtable();
...
Customer customer = customers["Ali G"] as Customer;

しかし、 `Dictionary`はハッシュテーブルとして内部的に実装されているので、技術的には同じように機能します。


81


参考:.NETでは Hashtable`は複数のリーダースレッドと単一の書き込みスレッドで使用するのにスレッドセーフですが、 Dictionary`ではpublic staticメンバーはスレッドセーフですが、どのインスタンスメンバーもスレッドセーフであることは保証されていません。

このため、私たちはすべての辞書を `Hashtable`に戻す必要がありました。


65



30


人々は辞書はハッシュテーブルと同じであると言っています。

これは必ずしも真実ではありません。 ハッシュテーブルは辞書を実装する1つの方法です。 典型的なもので、それは `Dictionary`クラスの.NETのデフォルトのものかもしれませんが、定義上それだけではありません。

リンクリストや検索ツリーを使用して辞書を同様に実装することもできますが、それほど効率的ではありません(効率的な指標として)。


21


コレクション In .NET, all the collections objects comes under the interface IEnumerable、これは` ArrayList(Index-Value)) を持ちます .NET framework 2.0以降、 `ArrayList さて、 Arraylist

`HashTable`の違いに来る どんなタイプのオブジェクトでも `HashTable`に追加することができますが、取得している間それを必要なタイプにキャストする必要があります。 だから、それはタイプセーフではありません。 しかし `dictionary`では、それ自身を宣言しながらキーと値の型を指定できるので、検索中にキャストする必要はありません。

例を見てみましょう。

ハッシュ表

class HashTableProgram
{
    static void Main(string[] args)
    {
        Hashtable ht = new Hashtable();
        ht.Add(1, "One");
        ht.Add(2, "Two");
        ht.Add(3, "Three");
        foreach (DictionaryEntry de in ht)
        {
            int Key = (int)de.Key; //Casting
            string value = de.Value.ToString(); //Casting
            Console.WriteLine(Key + " " + value);
        }

    }
}

辞書、

class DictionaryProgram
{
    static void Main(string[] args)
    {
        Dictionary dt = new Dictionary();
        dt.Add(1, "One");
        dt.Add(2, "Two");
        dt.Add(3, "Three");
        foreach (KeyValuePair kv in dt)
        {
            Console.WriteLine(kv.Key + " " + kv.Value);
        }
    }
}


15


辞書:

  • 見つからないキーを見つけようとすると、例外を返す/スローします 存在します。

  • ボクシングとアンボクシングがないので、Hashtableより速いです。

  • スレッドセーフなのはパブリック静的メンバーだけです。

  • 辞書は一般的なタイプであるため、どのデータでも使用できます。 type(作成時には、キーと値の両方のデータ型を指定する必要があります)。 例: Dictionary = new Dictionary();

  • Dictionayは、Hashtable、 Keys、および 「値」は強く型付けされています。

ハッシュ表:

  • 存在しないキーを見つけようとするとnullを返します。

  • ボクシングとアンボクシングが必要なので、辞書より遅くなります。

  • Hashtable内のすべてのメンバーはスレッドセーフです。

  • Hashtableはジェネリック型ではありません、

  • Hashtableは緩やかに型付けされたデータ構造であり、キーと値を追加できます あらゆるタイプの。


14


NET Framework 3.5以降、http://msdn.microsoft.com/en-us/library/bb359438.aspx [HashSet]もあり、これはhttp://msdn.microsoft.com/の長所をすべて提供します。キーだけが必要で値が必要ない場合はen-us / library / xfhwa508.aspx [Dictionary]。

そのため、 Dictionary`を使用し、常にタイプセーフハッシュテーブルをシミュレートするために null`に設定する場合は、おそらくhttp://msdn.microsoft.com/ja-jp/library/bb359438.aspxに切り替えることを検討する必要があります。 [HashSet]。


14


MSDNのhttp://msdn.microsoft.com/en-US/library/ms379571(v=vs.80).aspx [C#を使用したデータ構造の広範な検証]記事には、衝突にも違いがあると述べています。解決戦略

Hashtableクラスは* rehashing *と呼ばれる手法を使います。

_ 再ハッシュは次のように機能します:ハッシュの異なる関数のセット、H〜1〜…​ そして、ハッシュテーブルからアイテムを挿入または検索するとき、最初はハッシュ関数H -1が使用されます。 これが衝突につながる場合は、代わりにH 2が試され、必要ならばH 2まで進行する。 _

辞書は*連鎖*と呼ばれるテクニックを使用します。

_ 再ハッシュでは、衝突が発生した場合、ハッシュが再計算され、ハッシュに対応する新しいスロットが試行されます。 ただし、連鎖を使用すると、衝突を保持するために2次データ構造が使用されます。 具体的には、ディクショナリ内の各スロットには、そのバケットにマップされる要素の配列があります。 衝突が発生した場合、衝突している要素がバケットのリストの先頭に追加されます。 _