function hashCode(str){ var h = 0, off = 0; var len = str.length; for(var i = 0; i < len; i++){ var tmp=str.charCodeAt(off++); h = 31 * h + tmp; if(h>0x7fffffff || h<0x80000000){ h=h & 0xffffffff; } } return h; };
今天写js 的 hashmap 算法, 需要用到java里的hashcode 算法,这是一个native method,封装在dll 里面了,看不到c 源码, 所以带往上看了一下:发现还是有人研究过的,code 如下:
function hashCode(str){ var h = 0, off = 0; var len = str.length; for(var i = 0; i < len; i++){ h = 31 * h + str.charCodeAt(off++); } var t=-2147483648*2; while(h>2147483647){ h+=t; } return h; }
偶不知道这位仁兄为什么要去减两个单位的2^32,但是这种做法是很不效率的,随便拿了一个字符串"大案要案噶dfi13"试了一下,IE就卡住了,
我把着个算法转成java的后确是对的,并且把减两个单位的while去掉了,也是对的,
private static int newHash(String str){ int h = 0, off = 0; int len = str.length(); for(int i = 0; i < len; i++){ h = 31 * h + str.charAt(off++); } return h; }
我马上知道怎么回事了,那个仁兄是想把js 的最后结果换成整型,不过他这么做十分不严谨,
我改了下子,只去低32位就可以了,因为java里有类型自动转换,偶写的也是如此...这下肯定没问题了...
function hashCode(str){
str=str+""; var h = 0, off = 0; var len = str.length; for(var i = 0; i < len; i++){ h = 31 * h + str.charCodeAt(off++); if(h>0x7fffffff || h<0x80000000){ h=h & 0xffffffff; } } return h; };