473,395 Members | 1,797 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

valid types for Keys (Hashtable, Dictionary)

Why can't I use an int[] for a key? Doing so evidently doesn't result in
unique IDs being generated. I can convert the array into a delimited string,
which works fine, but then I have a good deal of overhead parsing/casting the
ints back.
I'd obviously use a (jagged)multidimensional array of my Value type instead
of a key:value setup, but the int[] sets aren't tightly grouped, so I'd have
a lot (maybe 85%) of empty slots in the array. Still, speed is my priority,
so maybe it'd be best to just eat the memory cost? A full array would contain
~4 million items.
Dec 9 '05 #1
4 2994
Ok. I just put the ints into a struct and used that as a key. Problem solved.
Why didn't I think of that earlier?
Dec 9 '05 #2
Depending upon what you are doing, that may have been the wrong
solution. structs have very specific applications in .NET, and using
them without due consideration can lead to grief.

The reason that your int[]s didn't generate unique hash keys is that
Array uses the default GetHashCode() method inherited from Object,
which is documented as being no good for hashing. From the
documentation:

"The default implementation of GetHashCode does not guarantee
uniqueness or consistency; therefore, it must not be used as a unique
object identifier for hashing purposes."

The point is that there was no way for the .NET team to come up with a
one-size-fits all hash function, so they provided merely the signature
and left it up to individual classes to decide how to generate hash
keys.

So, the solution to your original problem is to create your own _class_
(probably not struct) to hold whatever it is you need to hold. That
class should then override GetHashCode() (and Equals()... they go hand
in hand) so that it can be used as a hash key.

Dec 9 '05 #3
> Depending upon what you are doing, that may have been the wrong
solution. structs have very specific applications in .NET, and using
them without due consideration can lead to grief.
So what is the specific utility of structs? I assumed that they were chiefly
a handy way to group value types, like Point and Vector3 do. It seemed
wasteful to me to make a class for three ints. I just assumed that object
creation is slower, but I guess that everything in .NET is an object anyway.
"The default implementation of GetHashCode does not guarantee
uniqueness or consistency; therefore, it must not be used as a unique
object identifier for hashing purposes."
Aha. I never came across that in my MS Press C# book. Most of the things
I've read about Hashtables stop short of explaining the nuts and bolts.
They're just some magical search tree to me.
So, the solution to your original problem is to create your own _class_
(probably not struct) to hold whatever it is you need to hold. That
class should then override GetHashCode() (and Equals()... they go hand
in hand) so that it can be used as a hash key.


In my particular situation, I'm primarily interested in being able to look
up a given object with a specific 3 int location, without having to create
throwaway object intermediaries for comparisons.
Perhaps for my purposes, since I know that none of the ints will be larger
than, say, X, I could create a unique number from my int[a,b,c] that is
a + (b*(X+1)) + (c*(X+1)*(X+1))
and use this in the overrides you mentioned.
I wish I knew exactly how .NET generated the default hash codes.

Thanks for the feedback.

Dec 9 '05 #4

Joseph Bergevin wrote:
Depending upon what you are doing, that may have been the wrong
solution. structs have very specific applications in .NET, and using
them without due consideration can lead to grief.
So what is the specific utility of structs? I assumed that they were chiefly
a handy way to group value types, like Point and Vector3 do. It seemed
wasteful to me to make a class for three ints. I just assumed that object
creation is slower, but I guess that everything in .NET is an object anyway.


When you declare a struct, you create a _value_ type. That means that
it acts like an int or a double. Whenever you assign it:

MyValudType b = new MyValueType(...);
MyValueType a = b;

it is copied, just like an int or a double. Whenever you put it in a
collection (such as an ArrayList or a Hashtable) it is boxed. In
particular, if you make your value type mutable (not recommended) then
you have to be very, very careful that you understand the exact
semantics so that when you change the value you know that it changes
and you know exactly where it changes and where it doesn't. (Using the
example above, if you were allowed to say a.MyProperty = 5 then b would
not change, because the contents of b were copied into a on
assignment.)

If in your case your three ints are spacial coordinates (x, y, z) and
they were immutable (that is, you couldn't say coord.X = 5), then a
struct would probably be the right way to go. If you make them mutable
(coord.X = 5 is legal) then you could use a struct, but you would have
to be very careful. (Search this newsgroup to see the kind of confusion
that the behaviour of System.Drawing.Point causes.)

The bottom line is that in .NET structs come with important semantic
considerations: value semantics versus reference semantics. As such,
they shouldn't be used in an offhand manner as a sort of "classes lite"
because they introduce major changes in behaviour.
In my particular situation, I'm primarily interested in being able to look
up a given object with a specific 3 int location, without having to create
throwaway object intermediaries for comparisons.
Well, keep in mind that the only thing you really save by using structs
is memory management costs of allocating space for an object and then
garbage collecting it later. That is, unless your structs are being
boxed (as they would be if you used them in a Hashtable either as keys
or values). In that case you don't save anything.

Microsoft made System.Drawing.Point a struct because (IMHO) they do a
lot of mathematics with points, and didn't want to create a gazillion
Point objects as a result of intermediate calculation results and then
have to garbage collect them all later. If it's just a question of the
Hashtable, then I would say that it's a non-issue: your decision as to
whether to use struct or class should rest with higher-level conceptual
issues, not with fine points of efficiency.
Perhaps for my purposes, since I know that none of the ints will be larger
than, say, X, I could create a unique number from my int[a,b,c] that is
a + (b*(X+1)) + (c*(X+1)*(X+1))
and use this in the overrides you mentioned.
Yes... that would probably be a good strategy, so long as X never
changes during a particular run of your program. Another way is to
leverage off of the existing GetHashCode method in int:

public override int GetHashCode()
{
return a.GetHashCode() + b.GetHashCode() + c.GetHashCode();
}

or even

public override int GetHashCode()
{
return a + b + c;
}

Remember... you're not after a unique value, just a value that will
provide a nice, even distribution across all ints.
I wish I knew exactly how .NET generated the default hash codes.


Well, the default for Object probably just returns zero or something,
or maybe a fixed value for each object type. Each of the Framework
classes that overrides GetHashCode has its own algorithm. I tend to
assume that those are good, and leverage off of them when I can. For
example, if my class needs to hash on two key string fields, I just say

return string1.GetHashCode() + string2.GetHashCode();

assuming that Microsoft pays math wizards big bucks to come up with
good hash functions for strings. :-)

Dec 9 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Steve D. Perkins | last post by:
Hello all - I'm a Java and C++ developer, looking to pick up some Python and wxPython skills for prototyping and quick projects. I've been developing for about 15 years, and am very familiar...
7
by: Torsten Mohr | last post by:
Hi, reading the documentation (and also from a hint from this NG) i know now that there are some types that are not mutable. But why is it this way? From an overhead point of view i think...
8
by: xmail123 | last post by:
Hi, As was pointed out whatever you return from a WebMethod needs to be serializable to SOAP. An ArrayList is not serializable. I will be needing to return other data types from web methods. ...
2
by: ESPNSTI | last post by:
Hi, I'm trying to use a generics dictionary with a key class that implements and needs IComparable<>. However when I attempt to use the dictionary, it doesn't appear to use the IComparable<> to...
5
by: Sky | last post by:
What makes something a valid DataSource? What methods/iterators/etc? Why do I ask? I do understand that a DataSet is based on an XML structure...but it's too table structured for what I am...
11
by: Crirus | last post by:
Easyest and fastest way... :) -- Ceers, Crirus ------------------------------ If work were a good thing, the boss would take it all from you ------------------------------
4
by: techiepundit | last post by:
I'm a Python newbie who just started learning the language a few weeks ago. So these are beginner questions. I have a list of sockets that I use for select.select calls like this: ...
11
by: garyhoran | last post by:
Hi Guys, I have a collection that contains various attributes (stuff like strings, DateTime and Timespan) . I would like to access the collection in various orders at different points in the...
8
by: Guy | last post by:
Is there a better way to search identical elements in a sorted array list than the following: iIndex = Array.BinarySearch( m_Array, 0, m_Array.Count, aSearchedObject ); aFoundObject= m_Array;...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.