Freigeben über


Hashtable-Klasse

Stellt eine Auflistung von Schlüssel-Wert-Paaren dar, die nach dem Hashcode des Schlüssels organisiert sind.

Namespace: System.Collections
Assembly: mscorlib (in mscorlib.dll)

Syntax

'Declaration
<SerializableAttribute> _
<ComVisibleAttribute(True)> _
Public Class Hashtable
    Implements IDictionary, ICollection, IEnumerable, ISerializable, _
    IDeserializationCallback, ICloneable
'Usage
Dim instance As Hashtable
[SerializableAttribute] 
[ComVisibleAttribute(true)] 
public class Hashtable : IDictionary, ICollection, IEnumerable, 
    ISerializable, IDeserializationCallback, ICloneable
[SerializableAttribute] 
[ComVisibleAttribute(true)] 
public ref class Hashtable : IDictionary, ICollection, IEnumerable, 
    ISerializable, IDeserializationCallback, ICloneable
/** @attribute SerializableAttribute() */ 
/** @attribute ComVisibleAttribute(true) */ 
public class Hashtable implements IDictionary, ICollection, 
    IEnumerable, ISerializable, IDeserializationCallback, ICloneable
SerializableAttribute 
ComVisibleAttribute(true) 
public class Hashtable implements IDictionary, ICollection, 
    IEnumerable, ISerializable, IDeserializationCallback, ICloneable

Hinweise

Jedes Element ist ein in einem DictionaryEntry-Objekt gespeichertes Schlüssel-Wert-Paar. Ein Schlüssel kann nicht NULL (Nothing in Visual Basic) sein, bei einem Wert ist dies hingegen möglich.

Die Objekte, die von einer Hashtable als Schlüssel verwendet werden, müssen die Object.GetHashCode-Methode (oder die IHashCodeProvider-Schnittstelle) und die Object.Equals-Methode (oder die IComparer-Schnittstelle) überschreiben. Die Implementierungen beider Methoden bzw. Schnittstellen müssen Groß- und Kleinschreibung auf gleiche Weise behandeln, andernfalls verhält sich die Hashtable möglicherweise fehlerhaft. Beim Erstellen einer Hashtable müssen Sie z. B. die CaseInsensitiveHashCodeProvider-Klasse (oder eine beliebige IHashCodeProvider-Implementierung, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird) mit der CaseInsensitiveComparer-Klasse (oder einer beliebigen IComparer-Implementierung, bei der die Groß- und Kleinschreibung ebenfalls nicht berücksichtigt wird) verwenden.

Diese Methoden müssen darüber hinaus dieselben Ergebnisse bei einem Aufruf mit denselben Parametern liefern, während sich der Schlüssel in der Hashtable befindet. Eine Alternative ist die Verwendung eines Hashtable-Konstruktors mit einem IEqualityComparer-Parameter. Wenn es sich bei der Schlüsselgleichheit nur um eine Verweisgleichheit handeln würde, wäre die geerbte Implementierung von Object.GetHashCode und Object.Equals ausreichend.

Schlüsselobjekte müssen unveränderlich sein, solange sie als Schlüssel in der Hashtable verwendet werden.

Ein zur Hashtable hinzugefügtes Element wird abhängig vom Hashcode des Schlüssels in einem Bucket abgelegt. Nachfolgend kann eine Suche über den Hashcode des gesuchten Schlüssels auf ein einzelnes Bucket beschränkt werden, wodurch sich die Zahl der erforderlichen Schlüsselvergleiche für das Auffinden eines Elements erheblich reduziert.

Der Lastfaktor einer Hashtable bestimmt das maximale Verhältnis von Elementen zu Buckets. Kleinere Lastfaktoren führen zu insgesamt kürzeren Suchzeiten bei einem größeren Speicherbedarf. Im Allgemeinen stellt der Standardlastfaktor 1,0 einen sinnvollen Kompromiss zwischen Geschwindigkeit und Größe dar. Ein abweichender Lastfaktor kann auch beim Erstellen der Hashtable angegeben werden.

Durch das Hinzufügen von Elementen zu einer Hashtable erhöht sich der tatsächliche Lastfaktor der Hashtable. Wenn der tatsächliche Lastfaktor den angegebenen Lastfaktor erreicht, wird die Anzahl der Buckets in der Hashtable automatisch auf die kleinste Primzahl erhöht, die größer als die doppelte Anzahl der derzeit in der Hashtable vorhandenen Buckets ist.

Jedes Schlüsselobjekt in der Hashtable muss über eine eigene Hashfunktion verfügen, auf die durch einen Aufruf von GetHash zugegriffen werden kann. Allerdings kann jedes Objekt, das IHashCodeProvider implementiert, an einen Hashtable-Konstruktor übergeben werden. Diese übergebene Hashfunktion wird für alle Objekte in der Tabelle verwendet.

Bei der Kapazität einer Hashtable handelt es sich um die Anzahl der Elemente, die die Hashtable enthalten kann. Die anfängliche Standardkapazität für eine Hashtable ist 0 (null). Beim Hinzufügen von Elementen zu einer Hashtable wird die Kapazität nach Bedarf automatisch durch Neureservierung erhöht.

Für die foreach-Anweisung in C# (for each in Visual Basic) ist der Typ jedes Elements in der Auflistung erforderlich. Da jedes Element der Hashtable ein Schlüssel-Wert-Paar ist, ist der Elementtyp nicht der Typ des Schlüssels oder Werts. Stattdessen ist der Elementtyp DictionaryEntry. Beispiel:

foreach (DictionaryEntry de in myHashtable) {...}
For Each de as DictionaryEntry In myHashtable
   ...
Next de

Die foreach-Anweisung ist ein Wrapper um den Enumerator, der nur das Lesen aus der Auflistung aber nicht das Schreiben in diese zulässt.

Da das Serialisieren und Deserialisieren einen Enumerators für eine Hashtable zu einer Neuanordnung der Elemente führen kann, ist es nicht möglich, die Enumeration ohne Aufrufen der Reset-Methode fortzusetzen.

Beispiel

Im folgenden Beispiel wird gezeigt, wie verschiedene Funktionen für Hashtable erstellt, initialisiert und ausgeführt werden und wie die entsprechenden Schlüssel und Werte ausgegeben werden.

Imports System
Imports System.Collections

Module Example

    Sub Main()

        ' Create a new hash table.
        '
        Dim openWith As New Hashtable()

        ' Add some elements to the hash table. There are no 
        ' duplicate keys, but some of the values are duplicates.
        openWith.Add("txt", "notepad.exe")
        openWith.Add("bmp", "paint.exe")
        openWith.Add("dib", "paint.exe")
        openWith.Add("rtf", "wordpad.exe")

        ' The Add method throws an exception if the new key is 
        ' already in the hash table.
        Try
            openWith.Add("txt", "winword.exe")
        Catch
            Console.WriteLine("An element with Key = ""txt"" already exists.")
        End Try

        ' The Item property is the default property, so you 
        ' can omit its name when accessing elements. 
        Console.WriteLine("For key = ""rtf"", value = {0}.", _
            openWith("rtf"))

        ' The default Item property can be used to change the value
        ' associated with a key.
        openWith("rtf") = "winword.exe"
        Console.WriteLine("For key = ""rtf"", value = {0}.", _
            openWith("rtf"))

        ' If a key does not exist, setting the default Item property
        ' for that key adds a new key/value pair.
        openWith("doc") = "winword.exe"

        ' The default Item property throws an exception if the requested
        ' key is not in the hash table.
        Try
            Console.WriteLine("For key = ""tif"", value = {0}.", _
                openWith("tif"))
        Catch
            Console.WriteLine("Key = ""tif"" is not found.")
        End Try

        ' ContainsKey can be used to test keys before inserting 
        ' them.
        If Not openWith.ContainsKey("ht") Then
            openWith.Add("ht", "hypertrm.exe")
            Console.WriteLine("Value added for key = ""ht"": {0}", _
                openWith("ht"))
        End If

        ' When you use foreach to enumerate hash table elements,
        ' the elements are retrieved as KeyValuePair objects.
        Console.WriteLine()
        For Each de As DictionaryEntry In openWith
            Console.WriteLine("Key = {0}, Value = {1}", _
                de.Key, de.Value)
        Next de

        ' To get the values alone, use the Values property.
        Dim valueColl As ICollection = openWith.Values

        ' The elements of the ValueCollection are strongly typed
        ' with the type that was specified for hash table values.
        Console.WriteLine()
        For Each s As String In valueColl
            Console.WriteLine("Value = {0}", s)
        Next s

        ' To get the keys alone, use the Keys property.
        Dim keyColl As ICollection = openWith.Keys

        ' The elements of the KeyCollection are strongly typed
        ' with the type that was specified for hash table keys.
        Console.WriteLine()
        For Each s As String In keyColl
            Console.WriteLine("Key = {0}", s)
        Next s

        ' Use the Remove method to remove a key/value pair.
        Console.WriteLine(vbLf + "Remove(""doc"")")
        openWith.Remove("doc")

        If Not openWith.ContainsKey("doc") Then
            Console.WriteLine("Key ""doc"" is not found.")
        End If

    End Sub

End Module

' This code example produces the following output:
'
'An element with Key = "txt" already exists.
'For key = "rtf", value = wordpad.exe.
'For key = "rtf", value = winword.exe.
'For key = "tif", value = .
'Value added for key = "ht": hypertrm.exe
'
'Key = dib, Value = paint.exe
'Key = txt, Value = notepad.exe
'Key = ht, Value = hypertrm.exe
'Key = bmp, Value = paint.exe
'Key = rtf, Value = winword.exe
'Key = doc, Value = winword.exe
'
'Value = paint.exe
'Value = notepad.exe
'Value = hypertrm.exe
'Value = paint.exe
'Value = winword.exe
'Value = winword.exe
'
'Key = dib
'Key = txt
'Key = ht
'Key = bmp
'Key = rtf
'Key = doc
'
'Remove("doc")
'Key "doc" is not found.
using System;
using System.Collections;

class Example
{
    public static void Main()
    {
        // Create a new hash table.
        //
        Hashtable openWith = new Hashtable();
        
        // Add some elements to the hash table. There are no 
        // duplicate keys, but some of the values are duplicates.
        openWith.Add("txt", "notepad.exe");
        openWith.Add("bmp", "paint.exe");
        openWith.Add("dib", "paint.exe");
        openWith.Add("rtf", "wordpad.exe");
        
        // The Add method throws an exception if the new key is 
        // already in the hash table.
        try
        {
            openWith.Add("txt", "winword.exe");
        }
        catch
        {
            Console.WriteLine("An element with Key = \"txt\" already exists.");
        }

        // The Item property is the default property, so you 
        // can omit its name when accessing elements. 
        Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);
        
        // The default Item property can be used to change the value
        // associated with a key.
        openWith["rtf"] = "winword.exe";
        Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);
        
        // If a key does not exist, setting the default Item property
        // for that key adds a new key/value pair.
        openWith["doc"] = "winword.exe";

        // The default Item property throws an exception if the requested
        // key is not in the hash table.
        try
        {
            Console.WriteLine("For key = \"tif\", value = {0}.", openWith["tif"]);
        }
        catch
        {
            Console.WriteLine("Key = \"tif\" is not found.");
        }

        // ContainsKey can be used to test keys before inserting 
        // them.
        if (!openWith.ContainsKey("ht"))
        {
            openWith.Add("ht", "hypertrm.exe");
            Console.WriteLine("Value added for key = \"ht\": {0}", openWith["ht"]);
        }

        // When you use foreach to enumerate hash table elements,
        // the elements are retrieved as KeyValuePair objects.
        Console.WriteLine();
        foreach( DictionaryEntry de in openWith )
        {
            Console.WriteLine("Key = {0}, Value = {1}", de.Key, de.Value);
        }

        // To get the values alone, use the Values property.
        ICollection valueColl = openWith.Values;
        
        // The elements of the ValueCollection are strongly typed
        // with the type that was specified for hash table values.
        Console.WriteLine();
        foreach( string s in valueColl )
        {
            Console.WriteLine("Value = {0}", s);
        }

        // To get the keys alone, use the Keys property.
        ICollection keyColl = openWith.Keys;
        
        // The elements of the KeyCollection are strongly typed
        // with the type that was specified for hash table keys.
        Console.WriteLine();
        foreach( string s in keyColl )
        {
            Console.WriteLine("Key = {0}", s);
        }

        // Use the Remove method to remove a key/value pair.
        Console.WriteLine("\nRemove(\"doc\")");
        openWith.Remove("doc");
        
        if (!openWith.ContainsKey("doc"))
        {
            Console.WriteLine("Key \"doc\" is not found.");
        }
    }
}

/* This code example produces the following output:

An element with Key = "txt" already exists.
For key = "rtf", value = wordpad.exe.
For key = "rtf", value = winword.exe.
For key = "tif", value = .
Value added for key = "ht": hypertrm.exe

Key = dib, Value = paint.exe
Key = txt, Value = notepad.exe
Key = ht, Value = hypertrm.exe
Key = bmp, Value = paint.exe
Key = rtf, Value = winword.exe
Key = doc, Value = winword.exe

Value = paint.exe
Value = notepad.exe
Value = hypertrm.exe
Value = paint.exe
Value = winword.exe
Value = winword.exe

Key = dib
Key = txt
Key = ht
Key = bmp
Key = rtf
Key = doc

Remove("doc")
Key "doc" is not found.
 */

Vererbungshierarchie

System.Object
  System.Collections.Hashtable
     System.Configuration.SettingsAttributeDictionary
     System.Configuration.SettingsContext
     System.Data.PropertyCollection

Threadsicherheit

Hashtable ist bei Verwendung durch mehrere Readerthreads oder einen einzelnen Schreibthread threadsicher. Bei Verwendung mehrerer Threads ist es nicht threadsicher, wenn Threads Schreibvorgänge (Aktualisierungen) ausführen. Um mehrere Writer zu unterstützen, müssen alle Operationen für Hashtable über den von der Synchronized-Methode zurückgegebenen Wrapper erfolgen, vorausgesetzt, dass keine Threads das Hashtable-Objekt lesen.

Die Enumeration einer Auflistung ist systemintern keine threadsichere Prozedur. Selbst wenn eine Auflistung synchronisiert wird, besteht die Möglichkeit, dass andere Threads sie ändern. Dies führt dazu, dass der Enumerator eine Ausnahme auslöst. Sie können während der Enumeration Threadsicherheit gewährleisten, indem Sie entweder die Auflistung während der gesamten Enumeration sperren oder die Ausnahmen abfangen, die durch Änderungen ausgelöst werden, die von anderen Threads vorgenommen werden.

Plattformen

Windows 98, Windows 2000 SP4, Windows CE, Windows Millennium Edition, Windows Mobile für Pocket PC, Windows Mobile für Smartphone, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

.NET Framework unterstützt nicht alle Versionen sämtlicher Plattformen. Eine Liste der unterstützten Versionen finden Sie unter Systemanforderungen.

Versionsinformationen

.NET Framework

Unterstützt in: 2.0, 1.1, 1.0

.NET Compact Framework

Unterstützt in: 2.0, 1.0

Siehe auch

Referenz

Hashtable-Member
System.Collections-Namespace
IDictionary
IHashCodeProvider
Object.GetHashCode
Object.Equals
DictionaryEntry-Struktur
System.Collections.Generic.Dictionary
IEqualityComparer