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);
}
}
}

发表评论

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

WordPress.com 徽标

您正在使用您的 WordPress.com 账号评论。 登出 /  更改 )

Google photo

您正在使用您的 Google 账号评论。 登出 /  更改 )

Twitter picture

您正在使用您的 Twitter 账号评论。 登出 /  更改 )

Facebook photo

您正在使用您的 Facebook 账号评论。 登出 /  更改 )

Connecting to %s