日期:2014-05-16  浏览次数:20365 次

javascript 实现 java 中String的hashcode方法

javascript中有需要用到像类似java中的hashcode方法,想把java中的hashcode方法直接搬到js中发现不行

/**
     * Returns a hash code for this string. The hash code for a
     * <code>String</code> object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
     * </pre></blockquote>
     * using <code>int</code> arithmetic, where <code>s[i]</code> is the
     * <i>i</i>th character of the string, <code>n</code> is the length of
     * the string, and <code>^</code> indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    public int hashCode() {
	int h = hash;
        int len = count;
	if (h == 0 && len > 0) {
	    int off = offset;
	    char val[] = value;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }

?关键是hash的类型是int,int的范围是MIN_VALUE = 0x80000000; MAX_VALUE = 0x7fffffff;

这样在执行

h = 31*h + val[off++];

?的时候当超有可能超过int的最大值,变成负数。但js里面是不区分int,long的直接显示,显示不下用科学技术法,所以需要一个模拟java中int超出范围变负数的方法。

最终的实现如下:

function isNull(str){
		return str == null || str.value == "";
	}
	
	/**
	 * java String hashCode 的实现
	 * @param strKey
	 * @return intValue
	 */
	function hashCode(strKey)
	{
		var hash = 0;
		if(!isNull(strKey))
		{
			for (var i = 0; i < strKey.length; i++)
			{
				hash = hash * 31 + strKey.charCodeAt(i);
				hash = intValue(hash);
			}
		}
		return hash;
	}

	/**
	 * 将js页面的number类型转换为java的int类型
	 * @param num
	 * @return intValue
	 */
	function intValue(num)
	{
		var MAX_VALUE = 0x7fffffff;
		var MIN_VALUE = -0x80000000;
		if(num > MAX_VALUE || num < MIN_VALUE)
		{
			return num &= 0xFFFFFFFF;
		}
		return num;
	}