Java subString 方法

jdk7之前substring实现方法

-截取一部分jdk的关键实现

String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

public String substring(int beginIndex, int endIndex) {
    //check boundary
    return  new String(offset + beginIndex, endIndex - beginIndex, value);
}

jdk7版本之后的实现

public String(char value[], int offset, int count) {
    //check boundary
    this.value = Arrays.copyOfRange(value, offset, offset + count);
}

public String substring(int beginIndex, int endIndex) {
    //check boundary
    int subLen = endIndex - beginIndex;
    return new String(value, beginIndex, subLen);
}

原因分析

从算法的时间复杂度方面来比较,第一个版本的复杂度为o(1), 第二个版本的复杂度为o(n),但是为什么jdk7之后要选用后面这个实现,只要是因为第一个实现会影响到垃圾回收,第一个版本调用substring不会分配新空间用于存储字符,使用的是原始字符串的字符数组,这样到时原始字符串即使没有了引用了空间也不会被回收,考虑一个特殊场景,当你有一个很长的字符串,但是每次只使用其中一个很小的子串,例如,一下这段程序很出现OOM:

public class TestGC {
    private String largeString = new String(new byte[100000]);
    private String smallString = "foo";

    String getString() {
        // if caller stores this substring, this object will not be gc'ed
        return this.largeString.substring(0,2);
//        return new String(this.largeString.substring(0,2)); // no error here!
//        return smallString; // no error here!
    }

    public static void main(String[] args) {
        java.util.ArrayList list = new java.util.ArrayList();
        for (int i = 0; i < 1000000; i++) {
            TestGC gc = new TestGC();
            list.add(gc.getString());
        }
    }
}

更详细的可以参考http://bugs.java.com/view_bug.do?bug_id=4513622
以及https://stackoverflow.com/questions/16123446/java-7-string-substring-complexity

你可能感兴趣的:(学习)