Sometimes the world is quite awful. You need a fast key access to a collection because of the performance of your application, and you need the garantuee that you can read the items in the same sequence like you put it in the list.
This scenario happend to me a few times during my career as a developer. In past I hold the elements twice in a hashtable and in a collection in order to have both – fast key access and the correct ordering. The problem was that this method causes a lot of overhead in managing the consistency of your data.
DotNet 2.0 offers a new collection called “KeyedCollection” which is one big step into the right direction. The problem is that the KeyedCollection ist abstract and therefore must be inherited, furthermore it does not implement the IDictionary interface.
That’s why I wrote a wrapper that is based on the new KeyedCollection and does implement the IDictionary interface. I called it HashList.
Look at this piece of code:
IDictionary contacts = new Dictionary();contacts.Add("a", contact_a);
contacts.Add("b", contact_b);
contacts.Add("c", contact_c);
Dump(contacts);
contacts.Remove("a");
contacts.Remove("b");
contacts.Remove("c");
contacts.Add("a", contact_a);
contacts.Add("b", contact_b);
contacts.Add("c", contact_c);
Dump(contacts);
a.) contact a
b.) contact b
c.) contact c
The second list is NOT in the right order anymore.
c.) contact c
b.) contact b
a.) contact a
Now the same piece of code using the new HashList (you can download it with the link at the end of the blog).
IDictionary contacts = new HashList();contacts.Add("a", contact_a);
contacts.Add("b", contact_b);
contacts.Add("c", contact_c);
Dump(contacts);
contacts.Remove("a");
contacts.Remove("b");
contacts.Remove("c");
contacts.Add("a", contact_a);
contacts.Add("b", contact_b);
contacts.Add("c", contact_c);
Dump(contacts);
a.) contact a
b.) contact b
c.) contact c
Now everything is ordered, like we had put them in the list.
a.) contact a
b.) contact b
c.) contact c
That’s my solution for using the KeyedCollection Microsoft offers. Hope you enjoy the hybrid between a Dictionary and a Collection.
The example can be downloaded using the following link:
New Dictionary: HashList – or How to build an ordered Hashtable
PS: Before I get another comment like the first one
. It’s not the intention of this example to sort the items by their Key. The intention is to keep the items in the same order like they have been put in the Hashtable.
August 9, 2006 at 9:37 am
Just a quick look at the documentation:
KeyedCollection: Provides the abstract base class for a collection whose keys are embedded in the values.
SortedDictionary: Represents a collection of key/value pairs that are sorted on the key.
1. There may be reasons to avoid SortedDictionary (“The SortedDictionary generic class is a binary search tree …”, but KeyedCollection seems to be a worse choice.
2. Why keep a sorted list in the firts place? If you need sorted keys only at certain points if ever (the usual case) a simple helper method that takes a dictionary, copies the key collection into a temporary sortable collection, and sorts it will suffice. Apart from beeing more efficient it would add the additional bennefit that you could alos provide a comparer, thus your sorting criteria would not be hard coded.
HIH,
AJ.NET
August 9, 2006 at 9:40 am
The SortedCollection does only a sort for keys. The HashList I implemented allows a ordering like it has been done in a Collection.
That’s the advantage. No automatic ordering, but the garantuee that the values are stored like they have been added. Plus additional key access to the elements.
Cheers
Gerhard
August 14, 2006 at 4:16 pm
Hi .NET Pro’s;
Sorted data is exaclty what the Oracle Server never can assure; You must always add an order by to a query to have a sorted result set.
Karl
October 30, 2007 at 2:19 am
This kicks ass! Thanks for sharing.
May 6, 2008 at 7:30 pm
Hi, I thought about sending an email to you, but cannot find it from your blog.
I need to count the number of instances of certain IDs, so I searched and found your hashlist.
I tried your HashList code. I think there is a bug, maybe when the value is of type int.
The bug is that it does not keep the order objects are added to the HashList object. In my case, the values are of type integer, and the HashList gets sorted by the int values as they are updated. See the VS2005 debugger screen shot at the following URL.
http://farm4.static.flickr.com/3134/2471033201_dfce8f6bf3_o.png