Q:

why does new Integer(i).hashCode() return i?

I want to know why new Integer(i).hashCode() or new Long(i).hashCode() returns i but when hashCode() is invoked by some other object say new Double(345).hashCode(), it returns a random number. Why?

A:

Because the int value of an Integer perfectly satisfies and fully complies with the general contract of Object.hashCode():

The general contract of hashCode is:

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 hash tables.

In short:
The hash codes for 2 objects must be the same if equals() returns true and should be (but not required) different if equals() returns false. Also by the declaration of Object.hashCode() it must be an int. Ideally the hash code should depend on all the data that is hashed.
Hash code of Long
Long has to map 8 bytes to 4 bytes (size of an int). Current implementation of Long.hashCode() will only return i if it fits into an int, else it will be XOR'ed with the upper 32 bits (4 bytes):
return (int)(value ^ (value >>> 32));

Hash code of Double
Obviously the double value of a Double does not qualify for this. Double also has to map 8 bytes to 4 bytes.
Double.hashCode() will return a seemingly random value because floating point numbers (float and double) are not stored "nicely" (e.g. 2's complement like int or long) in the bytes that are reserved for them but using  IEEE 754 binary floating point standard and so mapping those 8 bytes to 4 (this is exactly what the implementation does) will not be a meaningful number as an int which uses 2's complement representation.
long bits = doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));

A:

A value of an integer is a good enough hash because it is just as unique as the unique integer number itself.
A double has to be hashed in some different manner because the hash here has to be an integer.

A:

Becase the implementation say it:
Returns a hash code for this Integer. 

Returns:a hash code value for this object, equal to the primitive int value represented by this Integer object.

707
708     public int hashCode() {
709         return value;
710     }

