Sorted Dictionaries
The Framework provides two dictionary classes internally structured such that their
content is always sorted by key:
• SortedDictionary<TKey,TValue>
• SortedList<TKey,TValue>*
(In this section, we will abbreviate <TKey,TValue> to <,>.)
SortedDictionary<,> uses a red/black tree: a data structure designed to perform
consistently well in any insertion or retrieval scenario.
SortedList<,> is implemented internally with an ordered array pair, providing fast
retrieval (via a binary-chop search) but poor insertion performance (because existing
values have to be shifted to make room for a new entry).
SortedDictionary<,> is much faster than SortedList<,> at inserting elements in a
random sequence (particularly with large lists). SortedList<,>, however, has an ex-
tra ability: to access items by index as well as by key. With a sorted list, you can go
directly to the nth element in the sorting sequence (via the indexer on the Keys/
Values properties). To do the same with a SortedDictionary<,>, you must manually
enumerate over n items. (Alternatively, you could write a class that combines a sorted
dictionary with a list class.)
None of the three collections allows duplicate keys (as is the case with all
dictionaries).
The following example uses reflection to load all the methods defined in
System.Object into a sorted list keyed by name, and then enumerates their keys
and values:
var sorted = new SortedList <string, MethodInfo>();
foreach (MethodInfo m in typeof (object).GetMethods())
sorted [m.Name] = m;
foreach (string name in sorted.Keys)
Console.WriteLine (name);
foreach (MethodInfo m in sorted.Values)
Console.WriteLine (m.Name + " returns a " + m.ReturnType);
Here’s the result of the first enumeration:
Equals
GetHashCode
GetType
ReferenceEquals
ToString
Here’s the result of the second enumeration:
Equals returns a System.Boolean
GetHashCode returns a System.Int32
GetType returns a System.Type
ReferenceEquals returns a System.Boolean
ToString returns a System.String
Notice that we populated the dictionary through its indexer. If we instead used the
Add method, it would throw an exception because the object class upon which we’re
reflecting overloads the Equals method, and you can’t add the same key twice to a
dictionary. By using the indexer, the later entry overwrites the earlier entry, pre-
venting this error.
You can store multiple members of the same key by making each
value element a list:
SortedList <string, List<MethodInfo>>
Extending our example, the following retrieves the MethodInfo whose key is "GetHash
Code", just as with an ordinary dictionary:
Console.WriteLine (sorted ["GetHashCode"]); // Int32 GetHashCode()
So far, everything we’ve done would also work with a SortedDictionary<,>. The
following two lines, however, which retrieve the last key and value, work only with
a sorted list:
Console.WriteLine (sorted.Keys [sorted.Count - 1]); // ToString
Console.WriteLine (sorted.Values[sorted.Count - 1].IsVirtual); // True
No comments:
Post a Comment