2012-12-30 136 views
5

我遇到了需要跟蹤的情況,如果我已經處理了特定的值。在這些情況下,我使用Dictionary(Of TKey, TValue)來跟蹤我處理的值。基本上,在處理每個值時,我將處理後的值插入字典中作爲關鍵字。當我想查看我是否已經處理了該值時,我使用ContainsKey方法查看該值是否存在於集合中。替代字典做快速鍵查找?

這很好,但我不得不在鍵值對的值一側插入一些東西。我只是使用List(Of T),但我希望Dictionary提供的哈希表查找的性能。 .Net中是否有更適合於此目的的數據收集?

+0

是否存在您可以使用'TValue'的輔助鍵?如果不是的話,你可以做的最好的就是一個'List '並且使用一個謂詞來查找。 – casperOne

+0

@casperOne:不,我只需要鑰匙。 – poke

+0

如果你已經鍵入一個屬性,但沒有第二個屬性來區分組中的項目(你真的在這裏做一個「group by」),那麼沒有字典可以幫助你。 – casperOne

回答

15

我會建議一個HashSet<T>。如果您只需要知道鑰匙已被使用,您可以輸入鑰匙。

這真的很簡單,太:

if (myHashSet.Add(key)) 
{ 
    // item wasn't in the hash set, so process it. 
} 

Add是像 「添加如果不存在。」如果添加了該項目,它將返回true。如果項目已經在集合中,它將返回false

或者,您可以使用Contains來測試,然後Add來添加。

+3

這就是爲什麼我喜歡這個網站:我沒有意識到HashSet甚至在這個答案之前就已經存在(我從1.0開始編寫.Net,所以有時候會有新東西潛入)。現在我知道了,我有更好的方法來解決一些問題。謝謝! –

+0

@competent_tech,如果你反編譯它們,你會看到HashSet使用與字典的密鑰集合相同的實現。 – phoog

0

您可能會使用System.Collections.Specialized.StringCollection,但我不確定它是否與Dictionary類似,並且需要您將鍵轉換爲字符串。

如果總是在Add方法中包含某些內容的要求令人討厭,那麼您可以創建自己的通用鍵類,該類可以適應更好的底層.Net實現。例如,假設VB.Net:

Public Class KeyDictionary(Of T) 
    Inherits Dictionary(Of T, Boolean) 

    Public Overloads Sub Add(key As T) 
     MyBase.Add(key, False) 
    End Sub 
End Class 

然後聲明一個實例,並添加一個值:

Dim cKeys As New KeyDictionary(Of Integer) 

    If Not cKeys.ContainsKey(1) Then 
     cKeys.Add(1) 
    End If 

而且,在C#:

public class KeyDictionary<T> : Dictionary<T, bool> 
{ 
    public void Add(T key) 
    { 
     base.Add(key, false); 
    } 
} 

聲明一個實例,並添加值:

 var cKeys = new KeyDictionary<int>(); 

     if (!(cKeys.ContainsKey(1))) 
     { 
      cKeys.Add(1); 
     } 
3

在.NET 3.5或更高版本上,您可以n爲此目的使用HashSet。您需要的方法稱爲AddContains。對於List,兩種操作都具有時間複雜度O(日誌n),而不是O(n)。

+2

實際上,'Add'和'Contains'是O(1)。請參閱文檔。 –

+0

@Jim Huh?似乎無法找到。 –

+0

在這裏的註釋:http://msdn.microsoft.com/en-us/library/bb353005.aspx。 「如果Count小於內部數組的容量,則此方法爲O(1)操作。如果必須調整HashSet對象的大小,則此方法變爲O(n)操作,其中n爲Count。」 –