Thursday, December 6, 2007

Java, HashSet, Equals and hashCode

Today, I was working on the code that attempts to add 2D points to java.util.HashSet and test if HashSet contains them.
Point implemented equals method correctly, and accoding to java.util.Set documentation contains should: "Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e))."

Well, documentation is wrong - and for a good reason - to implement specification as documented one would need to iterate all objects (in the set) for check for equality. What java.util.Set does is to use hashCode() value to index objects and compare them.

Therefore, if your class does not implement hashCode correctly, following test will fail:

ArrayList points = new ArrayList() ;
points.add( new IntPoint2D( 2, 2 ) ) ;
assertTrue(points.contains(new IntPoint2D(2,2)));

A dilemma is what to return as hashCode? I opted, knowing that my data will be local to implement hashCode as:

public int hashCode()
return (x & 0xffff) | ((y & 0xffff)<<16) ;

That will be good enough solution for the problem I'm facing.

There is corollary of this implementation:
1. if one assumes that hashCode() is natively implemented to return a pointer to underlying objects, and one tests for identity of the objects contained in the set (often the case) than Set works great.
2. if one needs to overload hashCode() and stuff more complex object in it, it needs to be aware of remote or not-so-remote chance that hashCode will return same value for two different objects, thereby yielding incorrect code.

Tuesday, August 7, 2007

Man isn't this useless, but cute...

Browsing for fast USB drives I found a useless feed. And this useless gadget is kind'a fun - check YouTube video.


Wednesday, August 1, 2007

Java and backward/forward compatibility

I just faced an issue with OrbitBehavior. Older Java3D don't have a field MOUSE_WHEEL_LISTENER, but it is a feature that I find very useful for my project (blog).

Here is a code on how I solved dynamical determination if runtime version of Java3D supports this new field without throwing an exception.

void addMouseWheelListener( int flags )
int listenerFlags = MOUSE_LISTENER | MOUSE_MOTION_LISTENER | flags ;
String field = "MOUSE_WHEEL_LISTENER";
Class parent = getClass().getSuperclass();
if( parent.getDeclaredField(field) != null )
int flag = parent.getDeclaredField(field).getInt(this);
listenerFlags |= flag ;
catch (SecurityException e)
catch (NoSuchFieldException e)
catch (IllegalArgumentException e)
catch (IllegalAccessException e)

As you can see I use reflection to check first if the field exist, and if and if it does I modify my listenerFlags with field's value.

Even if the field is visible in this class it does not need to be declared there. In my case field is declared in superclass.

Tuesday, July 31, 2007

How to resize Vmware disk with Windows OS VM

I was running a VMWare image. Given that I made image some time ago (like 2years or so), I made it with 2Gb disk partitions. 2Gb was too small to install .NET framework - and there was an issue.

To solve it I had few solutions, but easiest and most obvious one is to resize Windows partition to more space. Quick google search returned link to Carl Tyler's blog explaining how to use it.

Given that I had Ubuntu image handy on my laptop, resizing using QTParted was a breeze. I booted the image, and started doing install to HD process until I got to partition manager, selected size to grow from 2 to 8Gb and voile - I'm done.

Windows did notice something wasn't right on next reboot, it checked disk (chkdsk) and proceeded without a glitch.

Two thumbs up for Ubuntu. Thanks Carl :)

Add digg it to your site!

Given that this are my early blogging days - here's a useful page that explains how to add "digg it" button to your site.
I'll need to explore more features like this - like adding technorati link.

Monday, July 30, 2007

Double clicking on JNLP not working on MacOS X

This is 2nd or 3rd time we have faced this problem - double-clicking on JNLP file does not start on a MacOS X.

Well, this time I think we got the culprit - /Applications/Utilities/Java folder had an "Java SE 6" file in it - a left-over file from installation of Java 6 SDK Developer Preview. Removing that file solved the problem.

So, people, if you have a problem w/ running JNLP - that may be the solution.