.NET Framework 類別庫
Hashtable 類別

更新:2007 年 11 月

表示根據索引鍵的雜湊程式碼組織而成的索引鍵/值組集合。

命名空間:  System.Collections
組件:  mscorlib (在 mscorlib.dll 中)

語法

Visual Basic (宣告)
<SerializableAttribute> _
<ComVisibleAttribute(True)> _
Public Class Hashtable _
    Implements IDictionary, ICollection, IEnumerable, ISerializable,  _
    IDeserializationCallback, ICloneable
Visual Basic (使用方式)
Dim instance As Hashtable
C#
[SerializableAttribute]
[ComVisibleAttribute(true)]
public class Hashtable : IDictionary, ICollection, 
    IEnumerable, ISerializable, IDeserializationCallback, ICloneable
Visual C++
[SerializableAttribute]
[ComVisibleAttribute(true)]
public ref class Hashtable : IDictionary, 
    ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable
J#
/** @attribute SerializableAttribute */ 
/** @attribute ComVisibleAttribute(true) */
public class Hashtable implements IDictionary, 
    ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable
JScript
public class Hashtable implements IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable
備註

每個項目都是儲存在 DictionaryEntry 物件中的索引鍵/值組。索引鍵不可以是 nullNothingnullptrNull 參照 (即 Visual Basic 中的 Nothing),但值卻可以。

Hashtable 用來當做索引鍵的物件,必須覆寫 Object..::.GetHashCode 方法 (或 IHashCodeProvider 介面) 和 Object..::.Equals 方法 (或 IComparer 介面)。這兩種方法和介面的實作必須以相同的方式處理大小寫的問題,否則,Hashtable 可能無法正確作用。例如,建立 Hashtable 時,您必須使用 CaseInsensitiveHashCodeProvider 類別 (或任何不區分大小寫的 IHashCodeProvider 實作) 搭配 CaseInsensitiveComparer 類別 (或任何不區分大小寫的 IComparer 實作)。

而且,當索引鍵存在 Hashtable 中時,使用相同的參數呼叫這些方法必須產生相同的結果。替代方法是使用 Hashtable 建構函式搭配 IEqualityComparer 參數。如果索引鍵相等純粹是參考相等 (Reference Equality),那麼 Object..::.GetHashCodeObject..::.Equals 的繼承實作就足夠了。

只要索引鍵物件在 Hashtable 中做為索引鍵,索引鍵物件必須是不變的。

將元素加入 Hashtable 時,根據索引鍵的雜湊程式碼將元素放入雜湊桶 (Bucket)。後續的索引鍵查閱會使用索引鍵的雜湊程式碼只在一個特定的雜湊桶中進行搜尋,因此大致上可以降低尋找元素所需的索引鍵比較次數。

Hashtable 的載入因數決定雜湊桶元素的最大比例。較小的載入因數會加快增加記憶體消耗所花費的平均查閱時間。預設載入因數 1.0 通常會提供在速度和大小之間的最佳平衡。當建立 Hashtable 時,也可以指定不同的載入因數。

將元素加入 Hashtable 時,會增加 Hashtable 的實際載入因數。當實際載入因數達到指定的載入因數,Hashtable 中 Bucket 的數目會自動增加到大於 Hashtable Bucket 目前數目兩倍的最小質數。

Hashtable 中的每一個索引鍵物件必須提供自己的雜湊函式 (可以呼叫 GetHash 進行存取)。然而,任何實作 IHashCodeProvider 的物件可以傳遞至 Hashtable 建構函式 (Constructor),並且雜湊表中的所有物件是使用該雜湊函式。

Hashtable 的容量是 Hashtable 可以保存的項目數。元素加入 Hashtable 時,容量會依所需透過重新配置自動增加。

vb#c#

C# 語言 (在 Visual Basic 中為 for each) 的 foreach 陳述式 (Statement) 需要集合中每個元素的型別。由於 Hashtable 的各個項目都是機碼/值組配對,因此項目型別既不是機碼型別,也不是值型別。相反的,元素型別為 DictionaryEntry。例如:

C#
foreach (DictionaryEntry de in myHashtable) {...}
Visual Basic
For Each de as DictionaryEntry In myHashtable
   ...
Next de
vb#c#

foreach 陳述式是環繞列舉值的包裝函式,它只允許從集合讀取,而不允許寫入集合。

由於序列化及還原序列化 Hashtable 的列舉值可能會導致項目重新排序,因此不呼叫 Reset 方法不可能繼續列舉作業。

注意事項:

由於索引鍵可以繼承,而且其行為已變更,所以比較作業無法使用 Equals 方法來保證其絕對的唯一性。

範例

下列範例將示範如何建立、初始化和執行 Hashtable 的各種函式,以及如何將它的索引鍵和值列印出來。

Visual Basic
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"

        ' 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.
'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.
C#
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";

        // 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.
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.
 */
繼承階層架構

System..::.Object
  System.Collections..::.Hashtable
    System.Configuration..::.SettingsAttributeDictionary
    System.Configuration..::.SettingsContext
    System.Data..::.PropertyCollection
    System.Printing.IndexedProperties..::.PrintPropertyDictionary
執行緒安全

由多個讀取器 (Reader) 執行緒和單一寫入執行緒使用 Hashtable 是執行緒安全的。在只有其中一個執行緒執行寫入 (更新) 作業時供多重執行緒使用也屬於安全執行緒,只要寫入器已序列化至 Hashtable,這種作業便允許您進行無需鎖定的讀取作業。若要支援多個寫入器,Hashtable 上的所有作業必須透過 Synchronized 方法所傳回的包裝函式來完成,只要沒有執行緒在讀取 Hashtable 物件。

透過集合的列舉基本上並非安全的執行緒程序。即使集合經過同步化,其他的執行緒仍可修改該集合,使列舉值擲回例外狀況。若要保證列舉過程的執行緒安全,您可以在整個列舉過程中鎖定集合,或攔截由其他執行緒的變更所造成的例外狀況。

平台

Windows Vista, Windows XP SP2, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP Starter Edition, Windows Server 2003, Windows Server 2000 SP4, Windows Millennium Edition, Windows 98, Windows CE, Windows Mobile for Smartphone, Windows Mobile for Pocket PC, Xbox 360

.NET Framework 和 .NET Compact Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱 .NET Framework 系統需求

版本資訊

.NET Framework

支援版本:3.5、3.0、2.0、1.1、1.0

.NET Compact Framework

支援版本:3.5、2.0、1.0

XNA Framework

支援版本:2.0、1.0
請參閱

參考

標記 :


Page view tracker