I have a list of objects and I need to find an object as quickly as possible (by it's name property). What data-structure should I use? I know I can use a Dictionary, but there wont ever be more than 10 items 开发者_如何转开发in the list, and if I remember correctly the dictionary is implemented as an array if the collection contains 10 items or less.
Thanks.
MSDN recommends the ListDictionary for collections with 10 items or less:
This is a simple implementation of IDictionary using a singly linked list. It is smaller and faster than a Hashtable if the number of elements is 10 or less. This should not be used if performance is important for large numbers of elements.
You may want to consider the System.Collections.Specialized.ListDictionary
if you are certain there will be less than ten items.
Also consider the System.Collections.Specialized.HybridDictionary
which switches behaviour (with a small overhead) should the size increase above a threshold, handy if your assumption is wrong.
Since you want fastest possible lookup by a property you should use Dictionary<Key, Value>
. The size doesn't hurt you if you want fast lookup. It's not that a Dictionary<Key, Value>
of just 10 items or less is taking up a ton of memory. Dictionary<Key, Value>
has a constructor that takes an int to set the capacity.
Why not just use a Hashtable? It's in the System.Collections namespace.
For your case, KeyedCollection<TKey, TItem>
will do. It is a hybrid structure, the constructor takes a parameter to denote from what size onward the structure should switch from linear list to a hash based lookup. And yes it is generic.
One downside is it is an abstract class, so you will have to derive one yourself.
public class KeyedCollection<TKey, TItem> : System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
{
private readonly Func<TItem, TKey> m_keySelector;
public KeyedCollection(Func<TItem, TKey> keySelector)
: this(keySelector, null)
{
}
public KeyedCollection(Func<TItem, TKey> keySelector, IEqualityComparer<TKey> comparer)
: this(keySelector, comparer, 10)
{
}
public KeyedCollection(Func<TItem, TKey> keySelector, IEqualityComparer<TKey> comparer, int dictionaryCreationThreshold)
: base(comparer, dictionaryCreationThreshold)
{
m_keySelector = keySelector;
}
protected override TKey GetKeyForItem(TItem item)
{
return m_keySelector(item);
}
}
Then you could call it:
var foo = new KeyedCollection<Foo, string>(f => f.Name, null, 10);
精彩评论