Search code examples
javastringsubstringstringbuffer

String's substring function vs StringBuffer's substring function


I went through the String and StringBuffer API and it seems both works same internally when you call the substring method. Both have a ref to original char array (char[] original), so both are using same space. Then why is StringBuffer prefered? how is stringbuffer.substring(2,4) different then string.substring(2,4) then.

Substring method of StringBuffer:

public String substring(int start, int end) {
    return new String(value, start, end - start);  
}

Substring metohd of String:

public String substring(int beginIndex, int endIndex) {
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
       : new String(value, beginIndex, subLen);
}

Both substring variants then call the String constructor:

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

which calls below method of Arrays class:

public static char[] copyOfRange(char[] original, int from, int to) {
    // **char[] original**
   return copy;
}

Solution

  • It would be a mistake to judge the value of String against StringBuffer on a single point. Yes they are very similar in functionality when taking substrings. No this does not contribute to the argument as to whether to use one or the other.

    You should always use the best structure. String is immutable and should be used when immutability is required and in some edge cases. If you need to make changes to a CharSequence then it would be better/safer/faster/more memory efficient to use StringBuilder.

    Consider removing a part of a string. Compare how you can do it using a String and using a StringBuilder - see how much easier it is. It isn't just easier, it is more efficient. The String mechanism creates two new objects and then adds them together to make a third. The StringBuilder one just removes the section of the string.

    public void test() {
        String a = "0123456789";
        StringBuilder b = new StringBuilder(a);
        System.out.println("a=" + a + " b=" + b);
        a = a.substring(0, 2) + a.substring(5);
        b.delete(2, 5);
        System.out.println("a=" + a + " b=" + b);
    }