views:

136

answers:

4

Let's say I have the following class:

class ABC {
    private int myInt = 1;
    private double myDouble = 2;
    private String myString = "123";
    private SomeRandomClass1 myRandomClass1 = new ...
    private SomeRandomClass2 myRandomClass2 = new ...

    //pseudo code
    public int myHashCode() {
        return 37 *
               myInt.hashcode() *
               myDouble.hashCode() *
               ... *
               myRandomClass.hashcode()
    }
}

Would this be a correct implementation of hashCode? This is not how I usually do it(I tend to follow Effective Java's guide-lines) but I always have the temptation to just do something like the above code.

Thanks

A: 

Seems to me that unless you can guarantee that the product is a prime number you might get collision (though probably rare) between resulting hashcodes for an object

TheSteve0
There's absolutely no reason why a hashcode would have to be a prime number. Besides, something that is a product is, by its very definition, not a prime number.
jqno
@jqno: mathematically, yes, but limited precision changes things a bit. `7 * 613566757 == 3` is prime.
polygenelubricants
@polygenelubricants Sure, but do you wanna base a hashCode implementation on that :) ?
jqno
+11  A: 
polygenelubricants
Why not use the Commons Lang HashCodeBuilder?
ILMTitan
Decent IDE's like Eclipse have also a nice hashcode (and equals) generator.
BalusC
+2  A: 

Doing this sort of things is allowable by the contract. But so is always returning 1. There is a compile time flag in HotSpot to always return 1 for the identity hash vale. Such choices will, however, produce poor performance.

There is a particular problem with multiplication. Not only will a 0 hash value from a component annihilate the value, but powers of two will progressively zero the lower bits.

Commutative operators have the problem that rearrangements of values will cause a clash.

If there is a particular relationship between hash values of components, then addition will be particularly bad. (4, 6) and (2, 8) clashing, for instance.

Tom Hawtin - tackline
What is the identity hash value?
devoured elysium
@devoured elysium The hash value is guaranteed to be the same for a particuler instance. From `System.identityHashCOde` or unoverridden `Object.hashCode`.
Tom Hawtin - tackline
+1  A: 

No, but in practice it is almost certainly not a good idea. Most importantly you are not allowed to modify any of the fields that you use in the hash code. They all have to be constant.

If you modify one, this can happen: You insert the objecy in a HashSet, you change a fields, and then test if the object is in the HashSet. Although it is in there, due to the fact that the hash code changed, HashSet will not find it!

Carsten
That's a good point, but that's a Collections Framework contract, regardless of `hashCode` formula.
polygenelubricants
I think this probably applies to most cases outside the Collection Framework as well. In fact, are you aware of any use case that copes with a dynamically changing hash code?
Carsten