HashMap的hash()方法

基础知识回顾

哈希算法

因为Java的HashMap源码里面有个混淆函数hash(),我就想补一下哈希的定义。
哈希算法有以下三个特点

  • 安全,给定数据 M 容易算出哈希值 X ,而给定 X 不能算出 M ,或者说哈希算法应该是一个单向算法。
  • 两个不同的数据,要拥有不相同的哈希。
  • 长度固定,给定一种哈希算法,不管输入是多大的数据,输出长度都是固定的。

仔细想一下,如果哈希的长度是固定的,也就是取值范围是有限的,而输入数据的取值范围是无限的,所以总会找到两个不同的输入拥有相同的哈希。所以,哈希函数的安全性肯定是个相对概念。如果出现了两个不同输入有相同输出的情况,就叫碰撞,collision 。不同的哈希算法,哈希位数越多,也就基本意味着安全级别越高,或者说它的”抗碰撞性“就越好。

位的操作
  • 正数的反码=原码=补码
  • 负数的反码为符号位保持不变,其余各位取反
  • 负数的补码就是在补码的基础上+1
    在这里插入图片描述
逻辑运算符
  • >>>: 无符号右移

按二进制形式把所有的数字向右移动对应位数,低位移出(舍弃),高位的空位补零。对于正数来说和带符号右移相同,对于负数来说不同。
其他结构和>>相似。

  • ^ : 位异或

0^0=0, 1^0=1, 0^1=1, 1^1=0

  • | : 或运算

0|0=0, 0|1=1, 1|0=1, 1|1=1

  • & : 与运算

0&0=0, 0&1=0, 1&0=0, 1&1=1

  • ~ : 非运算

~1=0, ~0=1

B树 和 B+树

B+树主要底部的叶子节点,和相连的节点有链接指向的关系。回去还得翻一翻以前的Sqlserver的索引的知识。

HashMap的实现原理

源代码主要通过数组+链表实现的,数组就是常说的桶,只是桶里装的是“糖葫芦”式的链表,还是树结构的数据。

hash()方法

这个扰动函数就是解决哈希出现相同key值的hash输入的可能性。

  • 获取key自带的hashCode
  • h再进行无符号向右移动16位,也就是取h的高16位
  • 这样的话自己的高半区和低半区做异或,就是为了混合原始哈希码的高位和低位,以此来加大低位的随机性。
static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值