HashCode详解

Posted Cookie-a

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashCode详解相关的知识,希望对你有一定的参考价值。

(1)Hash表

 hash是一个函数,该函数中的实现就是一种算法,就是通过一系列的算法来得到一个hash值,这个时候,我们就需要知道另一个东西,hash表,通过hash算法得到的hash值就在这张hash表中,也就是说,hash表就是所有的hash值组成的,有很多种hash函数,也就代表着有很多种算法得到hash值,

(2)HashCode

hashcode就是通过hash函数得来的,通俗的说,就是通过某一种算法得到的,hashcode就是在hash表中有对应的位置。

hashCode比较的是哈希码,哈希码是由特定的哈希算法的出。

一个对象肯定有物理地址,也有人把hashcode说成是代表对象的地址,这里肯定会让读者形成误区,对象的物理地址跟这个hashcode地址不一样,hashcode代表对象的地址说的是对象在hash表中的位置,物理地址说的对象存放在内存中的地址 。 通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法就得到了hashcode 。

举个例子,hash表中有 hashcode为1、hashcode为2、(...)3、4、5、6、7、8这样八个位置,有一个对象A,A的物理地址转换为一个整数17(这是假如),就通过直接取余算法,17%8=1,那么A的hashcode就为1,且A就在hash表中1的位置。

(3) equals方法和hashcode的关系?

         1、如果两个对象equals相等,那么这两个对象的HashCode一定也相同

   2、如果两个对象的HashCode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,

存放于同一个位置。hashCode()只表示对象的哈希码,哈希码相同的对象不一定相等,反之,没有重写equals方法的前提下,两个对象相等,则hashCode一定相同

(4)为什么equals方法重写的话,建议也一起重写hashcode方法?

  (如果对象的equals方法被重写,那么对象的HashCode方法也尽量重写)

   举个例子,其实就明白了这个道理,

   比如:有个A类重写了equals方法,但是没有重写hashCode方法,看输出结果,对象a1和对象a2使用equals方法相等,按照上面的hashcode的用法,那么他们两个的hashcode肯定相等,但是这里由于没重写hashcode方法,他们两个hashcode并不一样,所以,我们在重写了equals方法后,尽量也重写了hashcode方法,通过一定的算法,使他们在equals相等时,也会有相同的hashcode值。

equals()方法

hashCode()方法

HashCode()函数详解

Interger

    public static int hashCode(int value) {
        return value;
    }

Interger类型数据的hashcode仅仅是返回其原有的值

Double

    public static int hashCode(double value) {
        long bits = doubleToLongBits(value);
        return (int)(bits ^ (bits >>> 32));
    }

bits是双精度规格化浮点数的二进制
Double类的数据的hashcode是返回bits右移32位然后与bits相异或的结果

浮点数的表示

技术分享图片
最高位是符号位(0为正,1为负)
其后的11位是阶码位以2为底,用移码表示,移码的偏置量是2^(11-1)-1=1023,
后52位是尾数的数值位。

例:浮点数是9.0

写成二进制则为1001,也可写成1.001×2^3.
符号位为0
浮点数的阶码为3+1023=1026=10000000010
数值位默认删除第一位整数位的1,只保留小数点后的数。为00100000补够后面的零
所以9.0的表示就是
0 
10000000010
0010000000000000000000000000000000000000000000000000

异或

当两个数不同时为1,相同时为0

0∧0=0,0∧1=1,1∧1=0,1∧0=1

String

    public static int hashCode(byte[] value) {
        int h = 0;
        int length = value.length >> 1;
        for (int i = 0; i < length; i++) {
            h = 31 * h + getChar(value, i);
        }
        return h;

byte[] value传过来的是String每一个字符转成ascii码后的数组.
至于为什么选择31作为乘子,可以看 这篇文章






以上是关于HashCode详解的主要内容,如果未能解决你的问题,请参考以下文章

java中hashcode()和equals()的详解

HashCode详解

Java中的equals和hashCode方法详解

Java之hashCode与equals深度剖析与源码详解

Java提高篇——equals()与hashCode()方法详解

Java中的equals和hashCode方法详解