Java 深入理解hashcode()方法——Boolean

11 篇文章 1 订阅
2 篇文章 0 订阅

Java 深入理解hashcode()方法——Boolean

环境:jdk1.8


    public static void main(String []args)
    {
        Boolean b2=true;
        Boolean b3=false;

        System.out.println("ture的hash值:"+b2.hashCode());
        System.out.println("false的hash值:"+b3.hashCode());
    }

输出结果:
ture的hash值:1231
false的hash值:1237

为什么会返回1231与1237这两个诡异的数字呢(虽然hashcode值一直都很诡异@_@)?

让我们打开Boolean的源码

/**
     * 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;

   }

为什么是1231和1237,而不是我们经常用的1和0?

然后查阅了资料,发现有一种解释如下:


不管使用什么哈希算法,其哈希函数都要极可能避免冲突。简单地说,不同的值要落在不同的存贮单元。认真观察,很容易发现1231和1237都是素数。使用素数的好处在于,对于不同数目的存贮单元m,1231和1237基本上都与其互质,除非m等于或数倍于1231和1237。这种情况下,true和false也能落到不同的单元去。


其实这也就是一般hash算法取值的默认规则,取素数。

一般来说,单个Boolean类型是没有求hashcode的需求的。
比如这样:

  public static void main(String []args)
    {
        HashMap<Boolean,String> map=new HashMap<Boolean, String>();
        map.put(true,"这是true");
        map.put(false,"这是false");
    }

此时的Boolean的hashcode规则怎么去取都是无所谓的,取0,1可以,取1231,1237也可以,因为key有且最多只有2种可能,所以必然不可能发生碰撞。

但是,Boolean的hashcode一般是作为整体的一部分而存在的,此时就需要考虑碰撞冲突问题了。
比如下列代码

class hashTest
{
    Boolean a;
    Boolean b;
    Boolean c;
    Boolean d;

    /**
     * 重写hashcode
     * @return
     */
    @Override
    public int hashCode()
    {
        int hashResult=0;
        hashResult = 31 * hashResult + a.hashCode();
        hashResult = 31 * hashResult + b.hashCode();
        hashResult = 31 * hashResult + c.hashCode();
        hashResult = 31 * hashResult + d.hashCode();
        return hashResult;
    }
}

很显然,当Boolean的hashcode默认取0,1时。。。。麻烦就大了,几乎每次都会发生碰撞。
而取1231,1237,对于不同数目的存贮单元m,1231和1237基本上都与其互质,除非m等于或数倍于1231和1237。所以发生碰撞的概率大大减小。

所以,Boolean的hashcode()采用了1231,1237两个素数,而不是其他,比如0,1.
而至于为啥不是其他素数,那估计Java源代码作者比较喜欢1231,1237,想留个彩蛋?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值