dark side of hash tables: mutable objects

If YourClass.java instance is to go into in a HashSet, then think of how you login to online banking. (Yes they are similar!)

JVM identifies each instance not by the physical address (necessarily unique), but by hashCode() and equals(). If another physical instance matches the first instance you put into the hashset, then system thinks they are identical. Similarly, if your wife knows your password, she can masquerade as you.

Now The darker side — if you forget your password, then you can’t access your money. For a given physical object, if state changes as to affect hashCode() or equals(), then JVM will think this instance is not the first instance put in. hashCode() must return exactly the same int, since that int determines which bucket … — think of separate chaining.

In the test below, once object changes state, it’s lost in the Set forever. The remove() and contains() operations can’t find it. Worse still, I managed to put the same object in it twice!

public class SetTest {
static Date d1 = new Date();
static Date d2 = new Date();
static Set Date> set = new HashSet Date>();
public static void main (String a[]) {
set.add(d1);
set.remove(d1);
dump();
set.clear();

set.add(d2);
printIfContains(d2);
d2.setHours(4);
printIfContains(d2);
set.remove(d2);
dump();
set.add(d2);
dump();
}
static void printIfContains(Date incoming) {
out.println("set.contians() === \t " + set.contains(incoming));
}
static void dump() {
out.println("size ==== \t" + set.size());
for (Date d: set) {
out.println(d);
}
}
}
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s