34

In the below code, the hash code is always same. Why is it like that?

Code:

public class BooleanClass {

    public static void main(String[] args) {
        Boolean b1 = new Boolean(true);
        Boolean b2 = new Boolean(false);
        Boolean b3 = new Boolean(true);
        Boolean b4 = new Boolean(false);
        Boolean b5 = new Boolean(false);
        Boolean b6 = new Boolean(true);

        System.out.println(b1.hashCode());
        System.out.println(b2.hashCode());
        System.out.println(b3.hashCode());
        System.out.println(b4.hashCode());
        System.out.println(b5.hashCode());
        System.out.println(b6.hashCode());
    }
}

Output:

1231
1237
1231
1237
1237
1231

Always the same numbers 1231 and 1237 are printed. Any reason?

Gokul Nath KP
  • 15,485
  • 24
  • 88
  • 126
user3467951
  • 439
  • 4
  • 5
  • 74
    If two objects are equal (in the sense of the equals method), they should (better must) also have the same hash code. – Seelenvirtuose Mar 27 '14 at 09:47
  • 26
    @Seelenvirtuose from the Javadoc: _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._ (emphasis mine). So your _should_ is too weak. – Boris the Spider Mar 27 '14 at 13:12
  • 2
    @BoristheSpider Got me. :-) But in fact, that _must_ is not a strict technical requirement. So you _could_ implement the hashCode method that produces distinct hash codes (as Object.hashCode does for example). Hmmm ... deeper thinking ... it becomes a technical requirement when dealing with hash data structures (HashMap e.g.), as they require the hashCode method implemented in the way, the Javadoc explains. So, you are completely right. – Seelenvirtuose Mar 27 '14 at 13:17
  • 3
    hashCode() that always returns 0 is correct implementation by definition, and if another implementation relies on "more proper" hashCode() for giving correct results, then this other implementation is broken. – Display Name Mar 27 '14 at 15:12
  • But of course if two "equal" objects do not return the same hash code it does not mean the end of the Universe or anything, simply that the objects will not "work and play well" with many other classes which depend on the prescribed behavior. The rule should never be intentionally violated without good reason (can't think of one off-hand) and without very visible comments and other documentation. – Hot Licks Mar 27 '14 at 15:23
  • 1
    I may think of only one use of violating `equals` and `hashCode` contracts: if you want to inflict damage to your company's project (and you need to hide the error) and even after that a skilled programmer will find your bug – Display Name Mar 27 '14 at 15:39
  • 9
    I will add that using boxed `Boolean` is *very wasteful*. But since there are only two values, and Boolean is immutable, you can use predefined `Boolean.TRUE` and `Boolean.FALSE` instead of creating new object if you need an object. – Display Name Mar 27 '14 at 15:43
  • 1
    This topic is covered well in [Effective Java](http://www.amazon.com/Effective-Java-Edition-Joshua-Bloch/dp/0321356683), chapter 9. To keep it short, if `object1.equals(object2) == true`, then you *should* aim for `object1.hashCode() == object2.hashCode()`. – 2rs2ts Mar 28 '14 at 18:49
  • @BoristheSpider What happens when somebody implements their hashCode method incorrectly and it does not produce the same integer result. That would make it that it should. – Flipper Mar 30 '14 at 06:13
  • By the definition of a hash, there *must* be collisions. Therefore, hashes are usually not used for equality comparisons. If they are used, they are used only to quickly filter through the negatives. For equality, the objects concerned must do a real compare. And if hashes are used to filter out negative comparisons, then the equal objects must yield the same hash. Hashes, AFAIK, are used primarily for putting things in hash tables, hash sorts, etc. – Stephen Chung Apr 02 '14 at 06:25

6 Answers6

161

The JavaDoc of Boolean.hashCode() method says:

Returns the integer 1231 if this object represents true; returns the integer 1237 if this object represents false.

Duncan Jones
  • 67,400
  • 29
  • 193
  • 254
Gokul Nath KP
  • 15,485
  • 24
  • 88
  • 126
  • 19
    If you add this to your answer, it will be the best answer: "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." – Danny Gloudemans Mar 27 '14 at 09:51
  • 21
    @WhoAmI: Check [this answer](http://stackoverflow.com/a/3912325/1343161) for an explanation. – Keppil Mar 27 '14 at 10:00
  • 9
    To summarize [the answer Keppil linked to](http://stackoverflow.com/questions/3912303/boolean-hashcode/3912325#3912325): 1231 and 1237 are just two arbitrary prime numbers, with the goal of reducing collisions in hashsets/hashmaps. – Flight Odyssey Mar 27 '14 at 21:30
51

The contract for hashCode() is:

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.

And while boolean has only two values, true and false, you get only two different hash Codes.

Harmlezz
  • 7,972
  • 27
  • 35
20

Straight from Boolean class:

 public int hashCode()
 {
   return ((this.value) ? 1231 : 1237);
 }

This is the method who generate hash code for Boolean type. That's why you always get same hash code for true or false.

and this is constructor of Boolean

 public Boolean(boolean paramBoolean)
 {
   this.value = paramBoolean;
 }

so this.value will be either true or false if true it will give 1231 and if false it will give 1237

Shekhar Khairnar
  • 2,643
  • 3
  • 26
  • 44
11

The point of a hashing function is to map data of arbitrary length to data of a fixed length. The values returned by a hash function are called hash values, hash codes, hash sums, checksums or simply hashes. A hash function will always return the exact same hash provided the input is the same, hence hashing true will always equal 1231 and hashing false will always equal 1237

Josh Roberts
  • 862
  • 6
  • 12
5

If you really need to distinguish instances rather than values -- which is VERY rarely what you actually want, but it does occasionally happen -- see IdentityHashMap.

(Essentially, IdentityHashMap bypasses both the .equals() and .hashcode() implementations in the object's "real" class and uses those from Object.)

keshlam
  • 7,931
  • 2
  • 19
  • 33
3

I do not understand why the question raised so much attention. I would be surprised if it would be otherwise. As it was nicely pointed by others, it is even specified in documentation.

But even if there is no documentation, it is easy to understand the reason: You can just check the definition of a hash function function.

A hash function is any algorithm that maps data of arbitrary length to data of a fixed length.

And from mathematical definition map is a function, which means that the same values will always produce the same value.

If this can not help, you can just look at this example:

 int a = 400;
 int b = 400;

Should you expect that the hashes will be different? Most probably no. So why should they be different in case of true and false?

Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
  • Good thought, but no. "Function", in programming languages, is not the same thing as mathematical function (obvious example: a stateful or context-sensitive function may return different data for the same parameters). Instead, this comes directly from the design of hashtables, which require that two values which are equal() are expected to have the same hashCode(). – keshlam Dec 20 '14 at 13:34