다음을 통해 공유


Hashtable 클래스

키의 해시 코드에 따라 구성되는 키/값 쌍의 컬렉션을 나타냅니다.

네임스페이스: System.Collections
어셈블리: mscorlib(mscorlib.dll)

구문

‘선언
<SerializableAttribute> _
<ComVisibleAttribute(True)> _
Public Class Hashtable
    Implements IDictionary, ICollection, IEnumerable, ISerializable, _
    IDeserializationCallback, ICloneable
‘사용 방법
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

설명

각 요소는 DictionaryEntry 개체에 저장된 키/값 쌍입니다. 키는 Null 참조(Visual Basic의 경우 Nothing)일 수 없으나 값은 null일 수 있습니다.

Hashtable에서 키로 사용하는 개체는 Object.GetHashCode 메서드(또는 IHashCodeProvider 인터페이스) 및 Object.Equals 메서드(또는 IComparer 인터페이스)를 재정의하는 데 필요합니다. 두 메서드 및 인터페이스 구현에서는 동일한 방식으로 대/소문자를 구분해야 합니다. 그렇지 않으면, Hashtable이 올바로 동작하지 않을 수 있습니다. 예를 들어, Hashtable을 만들 때 CaseInsensitiveComparer 클래스나 대/소문자를 구분하지 않는 IComparer 구현과 함께 CaseInsensitiveHashCodeProvider 클래스나 대/소문자를 구분하지 않는 IHashCodeProvider 구현을 사용해야 합니다.

또한 키가 Hashtable에 있는 동안에는 동일한 매개 변수를 사용하여 메서드를 호출할 때 동일한 결과가 생성되어야 합니다. 또는 IEqualityComparer 매개 변수와 함께 Hashtable 생성자를 사용할 수도 있습니다. 키 일치가 단순히 참조 일치이면 Object.GetHashCodeObject.Equals를 상속하여 구현하면 됩니다.

Hashtable에서 키 개체를 키로 사용하는 동안에는 해당 개체를 변경하지 않아야 합니다.

요소는 Hashtable에 추가될 때 키의 해시 코드에 따라 버킷에 배치됩니다. 키를 계속해서 조회하는 경우 해당 키의 해시 코드를 사용하여 특정 버킷 하나에서만 검색하므로 실제로 특정 요소를 찾는 데 필요한 키 비교 횟수가 줄어듭니다.

Hashtable의 로드 비율에 따라 버킷과 요소의 최대 비율이 결정됩니다. 로드 비율이 작을수록 메모리는 더 많이 소모되지만 평균 조회 시간은 빨라집니다. 일반적으로 기본 로드 비율 1.0은 적절한 속도와 크기를 제공합니다. Hashtable을 만들 때 다른 로드 비율을 지정할 수도 있습니다.

요소가 Hashtable에 추가되면 Hashtable의 실제 로드 비율이 증가합니다. 실제 로드 비율이 지정된 로드 비율에 도달하면 Hashtable의 버킷 수는 자동으로 현재 Hashtable 버킷 수의 두 배가 넘는 최소의 소수로 증가합니다.

Hashtable의 각 키 개체는 GetHash를 호출하여 액세스할 수 있는 자체 해시 함수를 제공해야 합니다. 그러나 IHashCodeProvider를 구현하는 개체는 Hashtable 생성자에 전달될 수 있으며 테이블의 모든 개체에 대해 해당 해시 함수가 사용됩니다.

Hashtable의 용량은 Hashtable에 보유할 수 있는 요소의 수입니다. Hashtable의 기본 초기 용량은 0입니다. 요소가 Hashtable에 추가될 때 필요하면 재할당을 통해 용량이 자동으로 증가됩니다.

C# 언어의 foreach 문(Visual Basic에서는 for each)은 컬렉션에 있는 각 요소의 형식을 필요로 합니다. Hashtable의 각 요소가 키/값 쌍이므로 요소 형식은 키의 형식도, 값의 형식도 아닙니다. 대신 요소 형식은 DictionaryEntry입니다. 예를 들면 다음과 같습니다.

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

foreach 문은 열거자를 둘러싸는 래퍼로 컬렉션에서 읽기만 가능하고 컬렉션에 쓰는 것은 허용되지 않습니다.

Hashtable의 열거자를 serialize 및 deserialize하면 요소가 다시 정렬될 수 있기 때문에 Reset 메서드를 호출해야만 열거를 계속할 수 있습니다.

예제

다음 예제에서는 Hashtable을 만들고 초기화하고 다양한 관련 기능을 수행하는 방법과 해당 키와 값을 출력하는 방법을 보여 줍니다.

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.
 */

상속 계층 구조

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

스레드로부터의 안전성

Hashtable은 여러 읽기 스레드 또는 단일 쓰기 스레드에서 사용할 때 스레드로부터 안전한 클래스입니다. 쓰기(업데이트) 작업을 수행하고 있는 스레드가 있는 경우에는 여러 스레드에서 사용할 때 스레드로부터 안전하지 않습니다. 여러 작성기를 지원하려면 Hashtable에 대한 모든 작업을 Synchronized 메서드에서 반환된 래퍼를 통해 수행해야 합니다. 단, 이때Hashtable 개체를 읽는 스레드가 없어야 합니다.

컬렉션을 열거하는 프로시저는 기본적으로 스레드로부터 안전하지 않습니다. 컬렉션이 동기화되어 있을 때 다른 스레드에서 해당 컬렉션을 수정할 수 있으므로 이렇게 되면 열거자에서 예외가 throw됩니다. 열거하는 동안 스레드로부터 안전을 보장하려면 전체 열거를 수행하는 동안 컬렉션을 잠그거나 다른 스레드에서 변경된 내용으로 인해 발생한 예외를 catch하면 됩니다.

플랫폼

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

.NET Framework에서 모든 플래폼의 모든 버전을 지원하지는 않습니다. 지원되는 버전의 목록은 시스템 요구 사항을 참조하십시오.

버전 정보

.NET Framework

2.0, 1.1, 1.0에서 지원

.NET Compact Framework

2.0, 1.0에서 지원

참고 항목

참조

Hashtable 멤버
System.Collections 네임스페이스
IDictionary
IHashCodeProvider
Object.GetHashCode
Object.Equals
DictionaryEntry 구조체
System.Collections.Generic.Dictionary
IEqualityComparer