Hash算法以及java hashmap的源码分析
来源:互联网 发布:js鼠标移入事件 编辑:程序博客网 时间:2024/04/30 12:27
hash算法也叫做散列函数,通过一个函数将任何信息转换成信息量的摘要。一个设计的比较好的hash算法,其冲突是比较少,冲突的含义就是不同的输入经过hash后得到了相同的摘要信息。
这里我分析了一下java源代码中HashMap的实现。
static int hash(int h) { // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }
这里可以针对任何类型的对象进行hash计算,之所以传入的是int类型,那是因为java object类中hashcode()方法。该方法的定义也比较有意思。
public native int hashCode(); 说明该方法是c++实现的。因此肯定要加载对应的dll文件。但是这里并没有发现加载什么dll文件。看看java代码里面的加载吧。
private static native void registerNatives(); static { registerNatives(); }我看到这里后,彻底晕倒了。我仅能得到的结论是:hashmap的实现中,java是将key值进行hashcode计算得到int类型,然后再hash计算得到摘要信息。看看hashmap的put方法吧。
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }这里首先调用了hash(key.hashCode())对key值进行hash,得出的值到table中查询,table是存放所有的值的数组,该数组的包含的对象是Entry对象,这个对象就像链表里面的节点一样。具体可以看看代码了。
然后对其hash值进行查找,并看table中该索引下的值是否为空,如果不为空的话,则在当前位置的元素中,建立一个链接,新建一个Entry对象,这样,在table数组当前的索引下,就是一个链表了。这是处理冲突的一种方法。如果table中该索引下的值是空的,说明使用正常,不存在冲突。
需要注意下哦,这里hash出来的值比较大,但是如何把这么大的值直接映射到这么小的数组空间上来呢,在indexFor()方法里面有一些眉目可以看到
static int indexFor(int h, int length) { return h & (length-1); }
经过与计算后,再大的值都会在数组空间范围内了。
关于java里面的hash就记录到这里了。
以下有一篇翻译的文章对理解hash比较有帮助。而且记录有各种hash算法。摘录以下代码记录一下。
http://blog.csdn.net/eaglex/article/details/6310727
package com.bplead.hash;public class Hash {public static long RSHash(String str){int b = 378551;int a = 63689;long hash = 0;for(int i=0;i<str.length();i++){hash = hash * a + str.charAt(i);a = a +b;}return hash;}public static long JSHash(String str){ long hash = 1315423911; for(int i = 0; i < str.length(); i++) { hash ^= ((hash << 5) + str.charAt(i) + (hash >> 2)); } return hash; } public long SDBMHash(String str){ long hash = 0; for(int i = 0; i < str.length(); i++) { hash = str.charAt(i) + (hash << 6) + (hash << 16) - hash; } return hash; } public long DJBHash(String str){ long hash = 5381; for(int i = 0; i < str.length(); i++) { hash = ((hash << 5) + hash) + str.charAt(i); } return hash; } public long DEKHash(String str){ long hash = str.length(); for(int i = 0; i < str.length(); i++) { hash = ((hash << 5) ^ (hash >> 27)) ^ str.charAt(i); } return hash; } public static int hash(int h) { // This function ensures that hashCodes that differ only by // constant multiples at each bit position have a bounded // number of collisions (approximately 8 at default load factor). h ^= (h >>> 20) ^ (h >>> 12); return h ^ (h >>> 7) ^ (h >>> 4); }public static void main(String[] args) {String temp = "HelloWorld12";int index = hash(temp.hashCode());System.out.println(index);System.out.println(index&15);}}
- Hash算法以及java hashmap的源码分析
- Java HashMap的hash算法
- hash算法及Java的HashTable源码分析
- Hashmap的hash算法
- HashMap源码分析(三)hash
- HashMap基础篇(1) 之Hash算法、Hash表以及冲突的处理
- Java HashMap 源码分析
- java HashMap源码分析
- Java源码分析:HashMap
- Java-HashMap源码分析
- [Java]HashMap源码分析
- Java HashMap源码分析
- 《Java源码分析》:HashMap
- java HashMap源码分析
- java hashmap 源码分析
- 《Java源码分析》:HashMap
- Java HashMap中hash方法的背景及分析
- hash算法 (hashmap 实现原理) Java实现的散列表
- menudrawer
- ESB就是各种webservice的组装平台
- 编程之美3.4 从无头单链表中删除节点
- 远程桌面怎样复制本地文件
- 深入理解HashMap,hash函数
- Hash算法以及java hashmap的源码分析
- LINUX自旋锁详解
- 触摸屏是一个符合人体工程学的解决方案吗
- 多校联合第九场1001HDU4686 Arc of Dream
- IPTV支持TS流的方案形成过程
- 如何检测apache配置文件是语法是否正确
- URAL 1146
- 站内搜索
- 实习第三周小记-----生活在于经历