A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 宋旭东 中级黑马   /  2013-7-4 08:45  /  1744 人查看  /  1 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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不会越界么?

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1

查看全部评分

1 个回复

倒序浏览
字符串内部使用字符数组来存储字符串,字符数组角标是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值不同的目的,只要编译不出错就欧了。

评分

参与人数 1技术分 +1 收起 理由
神之梦 + 1 很给力!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马