Look at this article by Brian Goetz. It goes into some detail, and provides links to other helpful resources at the bottom.
Basically, the hashCode method should return an int that is a quick and dirty means of telling if two instances of the same type are _not_ equal. Basically you calculate some numeric representation of your object based on its fields - the same fields you use to determine equality in the equals() method. If two objects are equal in terms of the equals() method, then they should produce the same hashCode(). If they are not equal in terms of equals() then they might or might not return the same hashCode() - if the hashCode() is well written then the chance of non-equal objects returning the same hashCode() should be low, but doesn't have to be zero. Also, if at all possible, an efficient hashCode() method should complete faster than an equals() method.