-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
Integer、String、Object等类的hashCode方法
我们知道,Java中的对象的hashCode方法非常重要,常用于Hash表的设计。这里我们来看看Java中的一些常见的类的hashCode的具体实现方法。
下面的代码都是从JDK10中复制的。
Boolean
/**
* Returns a hash code for this {@code Boolean} object.
*
* @return the integer {@code 1231} if this object represents
* {@code true}; returns the integer {@code 1237} if this
* object represents {@code false}.
*/
@Override
public int hashCode() {
return Boolean.hashCode(value);
}
/**
* Returns a hash code for a {@code boolean} value; compatible with
* {@code Boolean.hashCode()}.
*
* @param value the value to hash
* @return a hash code value for a {@code boolean} value.
* @since 1.8
*/
public static int hashCode(boolean value) {
return value ? 1231 : 1237;
}可以看到,Boolean类型的hash值很简单粗暴,True就是1231,Fasle就是1237。
但是JDK为什么选择了1231和1237这两个数呢?
Stack Overflow有个解释:
https://stackoverflow.com/questions/3912303/boolean-hashcode
首先为了减少hash冲突,我们应该选择质数,1231和1237都是质数。
然后不能选择太小的质数,否则会导致我们为组合对象编写hash方法是可能存在结果不均匀的现象。
所以选择一个不太小的质数就行了,这个类的设计者恰好就选择了这两个数。
Byte、Short、Integer
这三个类型的hash方法都是一样,就是返回当前对象对应的基本类型的值。
Byte
@Override
public int hashCode() {
return Byte.hashCode(value);
}
public static int hashCode(byte value) {
return (int)value;
}上面的value变量就是这个Byte对象对应的基本类型的值,下面同理。
Short
@Override
public int hashCode() {
return Short.hashCode(value);
}
public static int hashCode(short value) {
return (int)value;
}Integer
@Override
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}Long
我们知道hashCode的返回值应该是int类型,而long的基本的值是无法用int类型存储了,所以重要要做出一程转换
/**
* Returns a hash code for this {@code Long}. The result is
* the exclusive OR of the two halves of the primitive
* {@code long} value held by this {@code Long}
* object. That is, the hashcode is the value of the expression:
*
* <blockquote>
* {@code (int)(this.longValue()^(this.longValue()>>>32))}
* </blockquote>
*
* @return a hash code value for this object.
*/
@Override
public int hashCode() {
return Long.hashCode(value);
}
public static int hashCode(long value) {
return (int)(value ^ (value >>> 32));
}Long类型就是先把基本的值右移转换为整数,然后再取反。
Object
Object类的hashCode是个native方法
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by
* {@link java.util.HashMap}.
* <p>
* The general contract of {@code hashCode} is:
* <ul>
* <li>Whenever it is invoked on the same object more than once during
* an execution of a Java application, the {@code hashCode} method
* must consistently return the same integer, provided no information
* used in {@code 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.
* <li>If two objects are equal according to the {@code equals(Object)}
* method, then calling the {@code hashCode} method on each of
* the two objects must produce the same integer result.
* <li>It is <em>not</em> required that if two objects are unequal
* according to the {@link java.lang.Object#equals(java.lang.Object)}
* method, then calling the {@code 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.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined
* by class {@code Object} does return distinct integers for
* distinct objects. (The hashCode may or may not be implemented
* as some function of an object's memory address at some point
* in time.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
@HotSpotIntrinsicCandidate
public native int hashCode();具体的实现中,是根据运行时对象的地址来计算的。
String
todo