黑马程序员技术交流社区

标题: String类的HashCode方法问题 [打印本页]

作者: 宋旭东    时间: 2013-7-4 08:45
标题: String类的HashCode方法问题
public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;//字符数组表示字符串
        int len = count;//字符串字符个数

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }
上面是String类的HashCode() 方法的源码,问题是,当字符串无限长的时候,这个for循环计算得到hashCode不会越界么?
作者: longlangcx    时间: 2013-7-4 12:18
字符串内部使用字符数组来存储字符串,字符数组角标是int,那么字符串长度应该就不会超过Integer.MAX_VALUE, 具体多少没研究过,看网上有人说是直接赋值是65534(存储在常量池的那种),存储在堆内存中的话我自己用字符串链接测试连接到长度2000000还可以运行,20000000就溢出了,提示java堆内存溢出,如图:



其实上面说的是字符串的长度问题,但hashcode跟字符串长度其实没多大关系,因为31*h + val[off++]这里的运行结果就为int,赋值当然也没问题,就好像int i = 10000000 * 10000000;编译不会报错一样,虽然结果不对。hashcode要的不是运算结果对不对,而是在于只要不同的字符串hashcode不同就欧了。hashcode = 31*h + val[off++]按照这个公式,各种正数乘啊加啊的,是不会有负值的,但实际上hashcode有很多负值,比如"Hacker"的hashcode就是负的。这种负值的出现就是在运行当中溢出到符号位导致的,所以说这种溢出是合理存在的,因为依然可以达到不同的字符串hashcode值不同的目的,只要编译不出错就欧了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2