Różnica między słownikiem a Hashtable [duplikat]

Możliwy duplikat:
Dlaczego Słownik jest preferowany nad hashtable w C#?

Jaka jest różnica między słownikiem a Hashtable. Jak zdecydować, którego z nich użyć?

Author: Community, 2009-05-18

7 answers

Po prostu, Dictionary<TKey,TValue> jest typem generycznym, pozwalającym:

  • Statyczne typowanie (i weryfikacja w czasie kompilacji)
  • użyj bez boksu

Jeśli jesteś. NET 2.0 lub nowszy, powinieneś preferować Dictionary<TKey,TValue> (i inne zbiory rodzajowe)

Subtelną, ale ważną różnicą jest to, że Hashtable obsługuje wiele wątków czytnika z jednym wątkiem Writera, podczas gdy Dictionary nie zapewnia bezpieczeństwa wątku. Jeśli potrzebujesz bezpieczeństwa wątku ze słownikiem generycznym, musisz zaimplementować swój własna synchronizacja lub (w. NET 4.0) użycie ConcurrentDictionary<TKey, TValue>.

 188
Author: Marc Gravell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-03 16:53:49

Podajmy przykład, który wyjaśniałby różnicę między hashtable a dictionary.

Oto metoda implementująca hashtable

public void MethodHashTable()
{
    Hashtable objHashTable = new Hashtable();
    objHashTable.Add(1, 100);    // int
    objHashTable.Add(2.99, 200); // float
    objHashTable.Add('A', 300);  // char
    objHashTable.Add("4", 400);  // string

    lblDisplay1.Text = objHashTable[1].ToString();
    lblDisplay2.Text = objHashTable[2.99].ToString();
    lblDisplay3.Text = objHashTable['A'].ToString();
    lblDisplay4.Text = objHashTable["4"].ToString();


    // ----------- Not Possible for HashTable ----------
    //foreach (KeyValuePair<string, int> pair in objHashTable)
    //{
    //    lblDisplay.Text = pair.Value + " " + lblDisplay.Text;
    //}
}

Poniżej znajduje się słownik

  public void MethodDictionary()
  {
    Dictionary<string, int> dictionary = new Dictionary<string, int>();
    dictionary.Add("cat", 2);
    dictionary.Add("dog", 1);
    dictionary.Add("llama", 0);
    dictionary.Add("iguana", -1);

    //dictionary.Add(1, -2); // Compilation Error

    foreach (KeyValuePair<string, int> pair in dictionary)
    {
        lblDisplay.Text = pair.Value + " " + lblDisplay.Text;
    }
  }
 78
Author: Pritom Nandy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-10 11:49:16

Jest jeszcze jedna ważna różnica między HashTable a słownikiem. Jeśli użyjesz indeksatorów, aby uzyskać wartość z HashTable, HashTable pomyślnie zwróci null dla nieistniejącego elementu, podczas gdy Słownik wyświetli błąd, jeśli spróbujesz uzyskać dostęp do elementu za pomocą indexera, który nie istnieje w słowniku

 21
Author: Rohit Gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-16 03:04:45

Słownik jest wpisany (więc valuetypy nie potrzebują boksu), a Hashtable nie jest (więc valuetypy potrzebują boksu). Hashtable ma ładniejszy sposób uzyskania wartości niż słownik IMHO, ponieważ zawsze wie, że wartość jest obiektem. Chociaż jeśli używasz. NET 3.5, łatwo jest napisać metodę rozszerzenia dla dictionary, aby uzyskać podobne zachowanie.

Jeśli potrzebujesz wielu wartości na klucz, sprawdź mój kod źródłowy MultiValueDictionary tutaj: multimap w. Net

 11
Author: Frans Bouma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:17

Chcesz dodać różnicę:

Próba asess nieistniejącego klucza powoduje błąd środowiska uruchomieniowego w słowniku, ale nie ma problemu w hashtable, ponieważ zwraca null zamiast błędu.

Np.

       //No strict type declaration
        Hashtable hash = new Hashtable();
        hash.Add(1, "One");
        hash.Add(2, "Two");
        hash.Add(3, "Three");
        hash.Add(4, "Four");
        hash.Add(5, "Five"); 
        hash.Add(6, "Six");
        hash.Add(7, "Seven");
        hash.Add(8, "Eight");
        hash.Add(9, "Nine");
        hash.Add("Ten", 10);// No error as no strict type

        for(int i=0;i<=hash.Count;i++)//=>No error for index 0
        {
            //Can be accessed through indexers
            Console.WriteLine(hash[i]);
        }
        Console.WriteLine(hash["Ten"]);//=> No error in Has Table

Tutaj nie ma błędu dla klucza 0 i również dla klucza " ten " (Uwaga: t jest mały)

//Strict type declaration
        Dictionary<int,string> dictionary= new Dictionary<int, string>();
        dictionary.Add(1, "One");
        dictionary.Add(2, "Two");
        dictionary.Add(3, "Three");
        dictionary.Add(4, "Four");
        dictionary.Add(5, "Five");
        dictionary.Add(6, "Six");
        dictionary.Add(7, "Seven");
        dictionary.Add(8, "Eight");
        dictionary.Add(9, "Nine");
        //dictionary.Add("Ten", 10);// error as only key, value pair of type int, string can be added

        //for i=0, key doesn't  exist error
        for (int i = 1; i <= dictionary.Count; i++)
        {
            //Can be accessed through indexers
            Console.WriteLine(dictionary[i]);
        }
        //Error : The given key was not present in the dictionary.
        //Console.WriteLine(dictionary[10]);

Tutaj błąd dla klucza 0 i również dla klucza 10, ponieważ oba są nieistniejące w słowniku, błąd runtime, podczas próby acess.

 10
Author: Pranav Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-06 09:50:25

Klasa Hashtable jest specyficznym typem klasy słownika, która używa wartości całkowitej (zwanej hash), aby pomóc w przechowywaniu swoich kluczy. Klasa Hashtable używa hasha, aby przyspieszyć wyszukiwanie określonego klucza w kolekcji. Każdy obiekt w. NET wywodzi się z klasy Object. Ta klasa obsługuje metodę GetHash, która zwraca liczbę całkowitą, która jednoznacznie identyfikuje obiekt. Klasa Hashtable jest ogólnie bardzo wydajnym zbiorem. Jedyny problem z klasą Hashtable jest to, że wymaga trochę napowietrznych, a dla małych zbiorów (mniej niż dziesięć elementów) napowietrznych może utrudnić wydajność.

Istnieje pewna szczególna różnica między dwoma, które należy wziąć pod uwagę:

HashTable: jest zbiorem niestandardowym, największym tego kolekcji jest to, że robi to automatycznie dla Twoich wartości i aby uzyskać oryginalną wartość, musisz wykonać unboxing , te, aby zmniejszyć wydajność aplikacji jako kara.

Słownik: jest to rodzaj zbioru, w którym nie ma boks, więc nie trzeba rozpakowywać zawsze dostaniesz swój oryginalny wartości, które zostały zapisane, aby poprawić swoją aplikację wydajność.

Druga znacząca różnica to:

Jeśli próbujesz uzyskać dostęp do wartości z tabeli hash na podstawie klucz, który nie istnieje zwróci null.Ale w przypadku Słownik da ci KeyNotFoundException.

 6
Author: Rashmi Pandit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-03 22:14:17

Interfejs ILookup jest używany w. Net 3.5 z linq.

HashTable jest klasą bazową, która jest słabo typowa; DictionaryBase klasa abstrakcyjna jest ściśle wpisywana i używa wewnętrznie HashTable.

Znalazłem dziwną rzecz w słowniku, gdy dodajemy wiele wpisów w słowniku, kolejność, w jakiej wpisy są dodawane, jest zachowana. Tak więc, jeśli zastosuję foreach na słowniku, otrzymam rekordy w tej samej kolejności, w jakiej je wstawiłem.

Nie jest prawdą w przypadku zwykłej tabeli HashTable, ponieważ gdy dodaję te same rekordy w tabeli Hashtable, kolejność nie jest utrzymywana. Jeśli chodzi o moją wiedzę, Słownik opiera się na Hashtable, jeśli to prawda, dlaczego mój Słownik utrzymuje kolejność, ale HashTable nie?

Co do tego, dlaczego zachowują się inaczej, to dlatego, że słownik Generic implementuje hashtable, ale nie jest oparty na systemie.Kolekcje.Hashtable. Implementacja słownika generycznego opiera się na Przydzielaniu par klucz-wartość-z listy. Są to następnie indeksowane z Hashtable buckets dla losowego dostępu, ale gdy zwraca enumerator, po prostu przechodzi listę w kolejności sekwencyjnej - która będzie kolejnością wstawiania, dopóki wpisy nie zostaną ponownie użyte.

Shiv govind Birlasoft.:)

 3
Author: shiv govind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-04 20:12:56