在String的hashCode()中,偏移存在的原因是什么?似乎多余

时间:2013-06-28 04:39:04

标签: java

以下是hashCode()的{​​{1}}来源:

String

public int hashCode() { int h = hash; if (h == 0 && count > 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; } 初始化为off,为0(我在源代码中查找了所有内容,每个分配都将其设为0,这就是全部)。然后在offset循环中,for通过val而不是off进行迭代。为什么是这样?为什么不使用i并且不需要i开头?我认为offset存在的原因很充分。有什么见解吗?

3 个答案:

答案 0 :(得分:7)

substring函数创建一个新的String,其值不是0。

public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
    throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
    throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
    throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
    new String(offset + beginIndex, endIndex - beginIndex, value);
}

调用此构造函数。

// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}

所以偏移并不总是0。

答案 1 :(得分:5)

在Java中,字符串可以定义为父字符串的子字符串,以便在创建大字符串的许多子字符串时节省空间(例如解析它)。在这种情况下,他们使用偏移来确定它们在父字符串中的起始位置。

答案 2 :(得分:2)

偏移量和计数在旧版本中用于子串char数组共享。在当前版本中,不再使用共享,并且删除了这些字段。请参阅1.7.0_15中的hashCode impl

public int hashCode() {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;

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