Java: Hashcode Generation

Posted on

Creating your own Java classes you sometimes need to implement your own equals() method. When doing so you are highly encouraged by the Java compiler to also override and implement your own hashcode() function. A lot of the times we’re left wondering what to do and most of the times I see people just call super.hashcode() which is OK if you are not going to be using Hashtables in your program.

Yes, usually hashtables use your class’s hashcode for various purposes and most of the times if you have an issue with a hashtable you should check to see if you are implementing hashcode properly. According to Oracle Java API the hashcode function must follow the rules below:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

We are especially interested in the first 2 points. This is because according to my implementation of generating a hashcode, two objects have the same hashcode if they are equal to each other. And by equals I mean contain the exact same data. So if a class has 2 integers and 5 strings then another instance of the class that has exactly the same data of the 2 integers and the 5 strings (lexicographic equality) then they are equal and their hashcode should be the same.

Below is a Java function that accepts an indeterminate array of Strings. Each String is extracted into a character array where the ordinal value is multiplied by a prime number (31 in my case) and added to the previous product of the previous character. Just look at the last for-loop in the function 🙂

public static int generateHashCode(String ... args)
{
	int length = 0;
	char[] cArray = null;
	if(args.length == 1) {
		length = args[0].length();
		cArray = args[0].toCharArray();
	}
	else {
		for(int i = 0; i < args.length; i++) {
			length += args[i].length();
		}
			
		cArray = new char[length];
		int incrementer = 0;
		for(int i = 0; i < args.length; i++) {
			String str = args[i];
			for(int j = 0; j < str.length(); j++) {
				cArray[incrementer] = str.charAt(j);
				++incrementer;
			}
		}
	}
		
	int h = 0;
	for (int i = 0; i < cArray.length; i++) {
		h = 31*h + cArray[i];
	}
	
	return h;
}

The above function was originally written using StringBuilders, it’s performance was slow and it was better to bypass StringBuilder altogether and go directly for character arrays.

Sources that helped me:
http://www.javamex.com/tutorials/collections/hash_function_guidelines.shtml
http://mindprod.com/jgloss/hashcode.html

Advertisements

Leave a Comment

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s