just wondering:if I have two SortedDictionary objects, what is the fastest way to find out if their contents are the same? Looping all keys and checking the values does not sound like the best solution. Will it be enough to just check GetHashCode()?
Edit: I have tried around a bit. See this code:
SortedDictionary<string, string> o1 = new SortedDictionary<string, string>( );
SortedDictionary<string, string> o2 = new SortedDictionary<string, string>( );
o1["k1"] = "v1";
o1["k2"] = "v2";
o1["k3"] = "v3";
o2["k2"] = "v2";
o2["k1"] = "v1";
o2["k3"] = "v3";
Console.WriteLine( "o1:" );
foreach ( KeyValuePair<string, string> oKeyValuePair in o1 )
{
Console.WriteLine( oKeyValuePair.GetHashCode( ) );
}
Console.WriteLine( "o2:" );
foreach ( KeyValuePair<string, string> oKeyValuePair in o2 )
{
Console.WriteLine( oKeyValuePair.GetHashCode( ) );
}
Console.ReadKey( );
The hash codes for the individual key-value-pairs are the same for both sorted dictionaries, even though the order the开发者_如何学JAVA values were added differ. This is good. So I'm missing one step: how do I get ONE unique hash code from all the hash codes?
No, checking GetHashCode
wouldn't be enough even if SortedDictionary<,>
overrode it - which I don't believe it does.
As far as I'm aware, you do have to loop round checking all keys and values. Fundamentally that's what any solution would have to do. You should also check whether the comparison functions involved are the same, too... otherwise the dictionaries aren't really equivalent.
You will have to be prepared to loop through them all, but there are important short-cuts you can test for first.
First short-cut, is to check for object identity. While "A is A" isn't quite as profound as Ayn Rand seems to think, it is a handy way to make equality code faster. Identity always entails equality, and it is common in real code to end up comparing something to itself (esp in collection look-ups, loops and where an object is passed through several layers of code).
Another is that size cannot be different if contents are the same, and size is fast to obtain.
Hence the fastest you can get is:
public static bool EqualSortedDict<K, V>(SortedDictionary<K, V> x, SortedDictionary<K, V> y)
{
if(ReferenceEquals(x, y))
return true;
if(ReferenceEquals(x, null) || ReferenceEquals(y, null))
return false; //both being null already hit above.
if(x.Count != y.Count)
return false;
if(!x.Comparer.Equals(y.Comparer))
return false;//check if this is what you need. Probably is but might
//not be in some cases.
foreach(KeyValuePair<K, V> kvp in x)
{
V cmpValue = default(V);
if(!y.TryGetValue(kvp.Key, out cmpValue) || !kvp.Value.Equals(cmpValue))
return false;
}
return true;
}
Note that the reason GetHashCode() didn't work above is that the default implementation of GetHashCode() on SortedDictionary just works on object identity. If you need a value-based GetHashCode() (if your SortedDictionary will itself be a key or placed in a HashSet) then you will have to implement an IEqualityComparer that produces an appropriate hash code. Even then, it can take a long time to compute itself (it will probably always loop through all items to do what you want) and while a.GetHashCode() != b.GetHashCode() proves that a != b (for the definition of equality supported by the hashcode), a.GetHashCode() == b.GetHashCode() does not prove that a == b, as there will be collisions.
精彩评论