您的位置:首页 > 移动开发 > Objective-C

Object源码分析(二)-- hashcode方法

2017-09-22 11:19 411 查看
Object内还有一个hashcode方法,留给子类实现的,但是本身Object的hashcode方法也是可以返回一串hash值的,但是是基于C++写的,本人表示看不懂~~。
贴几个博客留待研究吧,表示确实不清楚是怎么得到,需要去研究C++去了。暂时读不懂. http://blog.csdn.net/luanlouis/article/details/41547649 http://blog.csdn.net/cor_twi/article/details/46554641

因此本篇其实是借由Object去研究一些常见类的hashcode实现。
1. 首先来看String的,
其实对于String来说的话,应该有一篇单独的文章去研究其内部的方法的,但是就先来看看吧。
value数组就是你String给的值,底层是放在一个数组内的 至于hash值,是一个int类型的变量。
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0

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;
}
hashcode内最主要的方法 就是  h = 31 * h + val[i]。
//Test str
String str = "abcd";

//默认值
h = 0;
value.legth = 4;

val[a];val;val[c];val[d];

//进入循环
i=0;
h = 31 * 0 + a = a;

i=1;
h = 31 * (31 * 0 + a) + b = 31 * a + b

i=2;
h = 31 * (31 * (31 * 0 + a) + b) + c = 31 * 31 * a + 31 * b + c

i=3;
h = 31 * (31 * (31 * (31 * 0 + a) + b) + c) + d = 31 * 31 * 31 * a + 31 * 31 * b + 31 * c + d

可以发现:
h = 31^(n-1) * val[0] + 31^(n-2) * val[1] + 31^(n-3) * val[2] + ....+val[n-1]
其实上过学的人都能总结出这个公式,但是这个公式是什么意思,肯定是参考的某些算法实现的吧,不然依据呢?比如,为什么系数是31。我肯定是不知道为什么的了,百度看看吧,学习学习。

可以参考这个帖子: http://www.it165.net/pro/html/201410/24949.html
这个算法叫BKDRhash算法;顺便学习一下,看看这个算法做了什么。具体不想再去搬运工了。
重点看它分析为什么取偶数是不行的,选择31的原因我看后觉得因为它是素数,被舍弃的只是偶数部分,但是 文章里分析的 “1”那一部分不参与运算的,其次 31(11111)占5bits,很小。
另外,联系到hashmap上我们可以知道,其实得到了这个hash值,并不是直接去使用的,而是再去把它 和数组 做 取余操作,得到最后真正的地址。那么即使发生碰撞了,也不要紧,可以采用链表法解决冲突。
另外装载因子= 添加的记录数 / hash表的大小 ,默认选择 0.75 就是想不至于 因子太小而造成 资源浪费。
hash分布

[b]2.  Integer 的hashcode

public int hashCode() {
return value;
}为什么只返回 value值就作为 hash值啊。

3. Long 的hashcode
public int hashCode() {
return (int)(value ^ (value >>> 32));
}
无符号右移32位 然后做 异或 操作。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: