Java 10:哈希

散列码是由对象导出的一个整数值。因为hashCode()定义在Object类中,因此每一个对象都有一个默认的散列值,为对象的存储地址。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能,HashMap对象是根据其Key的hashCode来获取对应的Value。

hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的

查看Object的hashCode函数,

public native int hashCode();
native是啥,简单查了下,写的比较杂,这里直接拷贝了别人的解释:

一个native方法就是一个Java调用非Java代码的接口,该方法由非Java语言实现

在定义一个native方法时,不提供实体(像是Java Interface),因为其实现在Java语言外

native是与C++联合开发的时候用的!java自己开发不用的! 
使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++语言实现的,并且被编译成了DLL,由java去调用。这些函数的实现体在DLL中,JDK的源代码中并不包含,你应该是看不到的。对于不同的平台它们也是不同的。这也是java的底层机制,实际上java就是在不同的平台上调用不同的native方法实现对操作系统的访问的。 

native的意思就是通知操作系统,这个函数你必须给我实现,因为我要使用。所以native关键字的函数都是操作系统实现的, java只能调用。 
java是跨平台的语言,既然是跨了平台,所付出的代价就是牺牲一些对底层的控制,而java要实现对底层的控制,就需要一些其他语言的帮助,这个就是native的作用了 


回到HashCode,就是说HashCode在不同平台下实现会不同,而且暂时我们看不到?

再看看String的hashCode函数,

  public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
为了验证是不是这么一回事,测试一下,这个hash默认的是0

那字符串“a”应该=31*0+a=97

      “aa”=31*97+97=3104

      “abc”=96354

测试了一下确实是的,但是问题来了,String长度增加时,hashCode岂不是迅速增大,一个int根本不够啊,测试了一个长字符串,返回的还是一个int(可能是负数),可能直接将多出的部分截断了,塞给了一个int型

再看一个几个实现:

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

public int hashCode() {
        return value;
    }Integer

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

public native int hashCode();自定义类



不同的类型计算方法是不同的

同样的内容的字符串String得到的HashCode是一样的,因为String的hashCode是由内容得到的

而同样内容的StringBuilder之间得到的Hash值却不同,因为StringBuilder自己没有实现HashCode函数,返回的是Object默认的方法(返回对象存储地址)


如果重新定义了equals方法,就必须重新定义hashCode方法,以便于用户可以将对象插入到散列表中。(13章里面讲,我才看到第五章啊)


总之,如果x和y通过equals相等,那他们的hashCode也必须相等。

但是反过来不一定,只能说明在散列存储结构中,存放在一个篮子里,但是不一定equals


hashCode是用于查找使用的















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值