Skip to content

Integer、String、Object等类的hashCode方法 #14

@bitfishxyz

Description

@bitfishxyz

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions