2

Im trying to understand what to return in a hashcode method.. For a string i know that ive to return(example) name.hashcode(). But what do i return for a int variable? ive seen different examples when they return the variable number x 1 000, but never understanded why.

Can anyone please explain for me how to return a integer value.

madhead
  • 25,830
  • 14
  • 131
  • 174
user2354898
  • 233
  • 2
  • 14
  • I don't understand either why one would multiply by 1000. Often just returning the value should be fine. – Keppil Sep 19 '14 at 11:58
  • 6
    possible duplicate of [What issues should be considered when overriding equals and hashCode in Java?](http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java) – Vincent Mimoun-Prat Sep 19 '14 at 11:59
  • 4
    This question gives all you need to know to understand hashCode and its purpose and how to implement it properly: http://stackoverflow.com/questions/27581/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java – Vincent Mimoun-Prat Sep 19 '14 at 12:00
  • Multiplying by 1000 is a very bad choice as it restricts the set of possible results. Note that the result will always have the last three bits set to 0. – Henry Sep 19 '14 at 12:02
  • It could always return `5` and that would be perfectly legit (though non-optimal). Returning the number itself is fine, though somehow "hashing" the number is probably a little better, in case the user of the value does not hash the value appropriately. (Eg, HashMap uses `h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4);` to "mix up" the bits a little.) However, java.lang.Integer simply returns the value, so that's good enough in Oracle's view. – Hot Licks Sep 19 '14 at 12:24

1 Answers1

0

If you have a class Foobar:

public class Foobar {
  private final int myInt;

  ... constructor ...

  public int hashCode() {
    return Integer.hashCode(myInt);
  }
}

Since Java 8, the method Integer.hashCode exists. Otherwise, you can use Integer.valueOf(myInt).hashCode().

Note: in the question, you'll read that hashCode and equals should not be based on mutable field, that's why I put final in declaration of myInt. In practice, it depends on use case (for example, Set based on a generated id in OneToMany in JPA) and where come your data.

Now as for the "good" hashCode, since it is used for hash based collection (map, set), you need to have a good repartition: imagine you return myInt % 1000, which means a value between 0 and 999; then this HashSet will not be efficient:

Set<Integer> set = new HashSet<Integer>(20); // initial capacity of 20
set.add(0);    // 0   [[0]]
set.add(1000); // 0   [[0, 1000]]
set.add(2000); // 0   [[0, 1000, 2000]]
set.add(3000); // 0   [[0, 1000, 2000, 3000]]
set.add(20);   // 20 -> 20 % 20 => 0 [[0, 1000, 2000, 3000, 20]]
set.add(21);   // 1  -> 1  % 20 => 1 [[0, 1000, 2000, 3000, 20], [1]]

In comments, and in the following order:

  • hashCode returned by myInt % 1000
  • if not trivial, index in internal HashSet array.
  • content of HashSet

The first four values (0 to 3000) will be stored at the same place, 20 will also be stored at the same place, but 21 at another place. Looking up a value require to iterate over the five values.

  • For Java Integer, it is the value (here, you could return myInt instead of calling Integer.hashCode)
  • For Java Long, it is some xor (using ^); see Long.hashCode.
  • For collection, it is in general the sum of P * o.hashCode() where P is a prime number; see Arrays.hashCode

But I don't remember the exact answer as to why you should use a prime number.

NoDataFound
  • 9,100
  • 27
  • 52