hashCode understanding

T

Tony Johansson

Hi!

Assume I have 2 instances of a class called Test see below which will work
as key in a hashtable. The Name property of instance1 is set to 'Paul', and
the Name property of instance2 is set to 'Piet'. Both instances will
generate different hashcode, and they're also different according to the
Equals method.So far so good. When looking up Piet I will get the value
object whatever it can be.
Now, suppose that I change the Name of instance2 to 'Paul', then, according
to my Equals method, both instances should be equal, and according to the
hashcode and equals method will generate the same hashCode(same key) and
that is not allowed
to have in a hashtable..
What is the solution to this senario ?

public class Test
{
string name;

public string Name
{
get
{
return name;
}
set
{
name = value;
}
}

public override GetHashCode()
{
return Name.GetHashcode();
}

public override Equals(object other)
{
Test myTest = other as Test;
if( myTest == null ) return false;
return this.Name == myTest.Name;
}
}
 
W

Willem van Rumpt

Tony said:
Hi!

Assume I have 2 instances of a class called Test see below which will work
as key in a hashtable. The Name property of instance1 is set to 'Paul', and
the Name property of instance2 is set to 'Piet'. Both instances will
generate different hashcode, and they're also different according to the
Equals method.So far so good. When looking up Piet I will get the value
object whatever it can be.
Now, suppose that I change the Name of instance2 to 'Paul', then, according
to my Equals method, both instances should be equal, and according to the
hashcode and equals method will generate the same hashCode(same key) and
that is not allowed
to have in a hashtable..
What is the solution to this senario ?

That would depend on the requirements for the classes themselves.
If two classes are presumed to be the same when their Name properties
are equal, then there is no solution.

If two instances of your class can have the same value for the Name
property, without reference equality, then your options are to either
alter GetHashCode() or Equals() to account for this.
 
T

Tony Johansson

Willem van Rumpt said:
That would depend on the requirements for the classes themselves.
If two classes are presumed to be the same when their Name properties are
equal, then there is no solution.

If two instances of your class can have the same value for the Name
property, without reference equality, then your options are to either
alter GetHashCode() or Equals() to account for this.

Hí!

Assume I have a HashTable pupulated with element(key,value) but always keep
the key unique can I then
update all of these element and change both the key and value as I wish if I
all the time keep the key unique ?

//Tony
 
W

Willem van Rumpt

Tony said:
Hí!

Assume I have a HashTable pupulated with element(key,value) but always keep
the key unique can I then
update all of these element and change both the key and value as I wish if I
all the time keep the key unique ?

I'm not sure if understand the question correctly.

If you're asking if you can add an element to a hashtable, then alter
(in what ever way) the hashcode (= key) for that element, while still
being able to retrieve it from the hashtable it was previously added to,
then, no.

The value can be changed without consequences.
 
J

Jeroen Mostert

Assume I have 2 instances of a class called Test see below which will work
as key in a hashtable. The Name property of instance1 is set to 'Paul', and
the Name property of instance2 is set to 'Piet'. Both instances will
generate different hashcode, and they're also different according to the
Equals method.So far so good. When looking up Piet I will get the value
object whatever it can be.
Now, suppose that I change the Name of instance2 to 'Paul', then, according
to my Equals method, both instances should be equal, and according to the
hashcode and equals method will generate the same hashCode(same key) and
that is not allowed
to have in a hashtable..
What is the solution to this senario ?
Don't change an object that's being used as a hashtable key in a way that
changes its hash code.

The best way to ensure this is to make the object immutable (making sure it
doesn't change *ever*). You can achieve what you want by removing the old
object, constructing a new one and adding that back to the table. If you
must have a mutable object, remove it from any hashtables (or HashedSets
or...) before changing it and add it back later.
 
P

Peter Duniho

Tony said:
[...]
Now, suppose that I change the Name of instance2 to 'Paul', then, according
to my Equals method, both instances should be equal, and according to the
hashcode and equals method will generate the same hashCode(same key) and
that is not allowed
to have in a hashtable..
What is the solution to this senario ?

Beyond the good advice you've already received, I'll point out that you
have not actually stated a _problem_ per se. So it's impossible to
propose a _solution_.

In particular, you've correctly stated the usage rules for hashtable
data structures, and you've intentionally implemented your class to
impose a specific usage restriction based on those rules. There does
not appear to be any actual problem. You simply have to work within the
rules.

If you don't like the constraints imposed on your code with your current
implementation, don't write code that imposes those constraints.

If you want a "solution" to some "problem", you need to state
specifically what that "problem" is.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top