您的位置:首页 > 编程语言 > Java开发

散列(HASH)---内含Java HashMap理解

2018-02-26 19:11 417 查看

散列是什么?

散列又称为hash,设K为key,那么则有存储位置下标 index = F(k).这里F做的事情
也就是我们本文要讲的散列,hash。通过散列算法。我们避免了循环比对,实现了不规
则数据高效率存取


Java HashMap 数组+链表



什么是hash碰撞

如上图,数组+链表,将我们的每一个KV的映射关系保存到了对象数组中。那么有:
PUT = F(K) = 构造entry对象 = insert entry array
GET = F(k) = 查找entry对象 = find single entry

看似完美,但是,key不相同,经过hash之后,下标位置不唯一有下列情况
index=F(KEY1)=F(KEY2)=F(KEY3)

我们的数组下标一个位置只能保存一个entry对象。但是现在KEY1,KEY2,KEY3全部
映射到了一个下标位置上。这就叫做hash碰撞


解决Hash碰撞

如上所述,hash算法其实没有完美的一对一的高效计算方式,它还是可能计算到相
同的数组下标位置,造成没有位置存储的尴尬,那么遇到这种情况,我们应该怎么办呢?
1-高效的算法(取模素数)
2-灵活的存储(next insert)


最大质数算法

为了减少hash冲撞,最大质数取模的算法只是其中一种,本篇,我们针对此算法做讨论

假设有一个数组容量为16.最大质数为13.那么
index=k.hashcode mod 13 = F(k)


问题:为什么用最大质数作为取模对象呢?

质数:又叫素数,定义为只能被1和它本身整除的数。
设数组容量size为Y,Y下面最大的素数为X,则Y>X
在KHC = k.hashcode不规则的情况下,有khc mod X = Z
那么Z只有在KHC = X本身 或 KHC = 1 或 KHC = X的倍数三种情况的时候Z才为0

如果X更换为非素数,那么,Z为0的次数变多了(可整除的次数增多),余数重复次数增
多,导致碰撞几率变大。

为什么是最大的质数?
设Y为16,那么16下的质数为1 3 5 7 11 13几个。
我们都知道余数<除数,也就是 Z<X.
那么 如果 X = 3 那么Z下标只有 0 1 2 三个位置可用。
而X = 5的时候, Z的取值范围为 0-4 五个位置可用。

由此可以推出,当取模用最大的质数的时候,导致余数为0的概率是最低的,也就是
hash冲突最小的时候.


PUT和GET 碰撞存取

entry的存储结构



hash put

HASH得到下标,如果下标内有entry对象,则取得entry.next 直到为null,则
放入entry对象,最后一个entry的next对象指向我们put对象,我们put进去的对象
next指向null




hash get

hash 获取entry。比对entry的key和当前传入的key,如果相同则return,不同则
next再次比对,直到相同return..




声明:

以上内容是笔者目前理解到的部分,仅用以交流,如有问题,欢迎指出,本篇未完待
续..
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: