您的位置:

Java StringBuilder

Java StringBuilder是一个可变的、线程不安全的字符序列,它在内存中以可变的方式来维护它们,用于缓存字符串。 StringBuilder类没有在实例化后重复创建一个新的对象,所以当需要进行多个字符串操作时它通常比String更加高效。

1. StringBuilder的背景信息

在Java String类中,字符串是不可变的对象,因此如果需要修改一个字符串,就需要创建一个新的String对象。这种机制可能会导致内存浪费和可维护性差的问题。Java StringBuilder为此而来。 StringBuilder提供了一种高效的字符串操作方式。使用StringBuilder可以避免在每次字符串操作时都重新创建一个新的String对象。它是自动扩容的,也可以手工调整其容量。其主要特点如下:
  • StringBuilder对象的长度和内容可以修改
  • StringBuilder对象可以在进行字符串操作时不需要额外开辟空间
  • StringBuilder对象可以自由进行扩容,缓冲器与创建字符数组的效果类似
  • StringBuilder对象可以直接和String对象进行互相转换

2. StringBuilder的详细阐述

一、StringBuilder与String的区别

StringBuilder对象可以在创建后进行内容的追加和修改,因此StringBuilder对象相关的API方法会比较多,而且在Java的API中,StringBuilder类和String类基本是对应的,两者有很多相似的方法。 不仅如此, stringBuilder还有一些独特的方法和属性使它更加实用。例如,StringBuilder对象可以通过反向追加字符串来构造一个全新的字符串,这在某些情况下会更加高效。

二、StringBuilder容量和长度的关系

当创建一个StringBuilder时,它的默认容量为16个字符(如有需要可以通过构造函数指定容量大小)。如果需要在StringBuilder中添加的字符超出其当前容量,StringBuilder会自动进行扩容。扩容时,产生的新数组大小为原数组大小的2倍+2。

三、StringBuilder的方法

StringBuilder类中有很多方法可以对其进行操作,下面列举几个最常用的方法:
//构造函数
StringBuilder()  //构造一个空的字符串构建器,容量为默认大小16
StringBuilder(CharSequence seq)  //构造一个字符串构建器,该构建器包含与指定的CharSequence相同的字符

//添加方法,将string,char,StringBuilder对象或其它对象加入再修改文本
append(String str)  //将指定字符串追加到此字符序列
append(char c)  //将指定字符追加到此字符序列
append(StringBuffer sb)  //将指定StringBuffer追加到此字符序列
append(CharSequence s)  //将指定CharSequence追加到此字符序列
append(Object obj)  //将指定对象的字符串表示形式追加到此字符序列
append(StringBuilder sb)  //将指定StringBuilder追加到此字符序列
append(CharSequence s, int start, int end)  //将指定CharSequence的子序列追加到此字符序列

//插入方法,在任意位置插入新的文本
insert(int offset, String str)  //将指定字符串插入此字符序列中
insert(int offset, CharSequence s)  //将指定CharSequence插入此字符序列中
insert(int dstOffset, CharSequence s, int start, int end)  //将指定CharSequence字符子集插入此字符序列
insert(int offset, boolean b)  //将boolean参数插入此字符序列
insert(int offset, char c)  //将char参数插入此字符序列中
insert(int offset, int i)  //将int参数插入此字符序列中
insert(int offset, long l)  //将long参数插入此字符序列中
insert(int offset, float f)  //将float参数插入此字符序列中
insert(int offset, double d)  //将double参数插入此字符序列中

3. StringBuilder小标题

1. StringBuilder与String的性能对比

在进行多次追加操作时,如果使用String对象进行操作,就需要每次创建一个新的对象。这样的话,在容量可预估的情况下,可以使用StringBuilder进行初始化,可以在程序的初始执行期就分配足够的内存以避免重新分配内存。 示例代码:
public static void main(String[] args) {

    //使用String
    long startTime = System.currentTimeMillis();
    String s = "";
    for (int i = 0; i < 10000; i++) {
        s += i;
    }
    long endTime = System.currentTimeMillis();
    System.out.println("String time cost: " + (endTime - startTime) + "ms");

    //使用StringBuilder
    startTime = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 10000; i++) {
        sb.append(i);
    }
    endTime = System.currentTimeMillis();
    System.out.println("StringBuilder time cost: " + (endTime - startTime) + "ms");
}
输出结果: String time cost: 38ms
StringBuilder time cost: 1ms 从上述代码和结果可知,使用StringBuilder进行字符串追加的效率要大大高于使用String。因此,在处理字符序列时,如果需要对其进行多次操作,则应优先考虑使用StringBuilder。

2. StringBuilder的线程安全问题

在单一线程环境下,StringBuilder比StringBuffer要快很多,但是在多线程的情况下StringBuilder是线程不安全的。 如果需要在多线程环境下使用StringBuilder,可以使用java.util.concurrent.atomic.AtomicReference,java.util.concurrent.atomic.AtomicLongFieldUpdater等线程安全类来进行替代实现。

3. StringBuilder的容量和长度的控制

StringBuilder默认的初始化容量为16个字符,如果在使用时发现StringBuilder未参考原始字符串的容量进行设定初始化容量,则每次进行扩容的时候都会重新申请新的内存空间对象,这样的开销将越来越大,直到StringBuilder的长度超过需要的字符串长度,扩容次数达到一定数量后,StringBuilder操作效率将直线下降。 因此,在使用StringBuilder时,如果提前知道字符串的长度,可以使用构造函数或者.ensureCapacity()方法对容量进行初始化。
StringBuilder sb1 = new StringBuilder();  //默认容量16
StringBuilder sb2 = new StringBuilder(32);  //容量为32
sb1.ensureCapacity(64);  //容量是64

4. 总结

StringBuilder是Java中十分优秀的字符串处理类,可以在性能和便捷性两个方面都拥有优势。在进行大批量字符串处理时,StringBuilder往往比原来的String类更加方便,也可以提高效率。但在多线程环境下需要考虑线程安全的问题,如果需要对文本进行手动操作,可以需要考虑容量和长度的问题。为了提高代码的可读性和易维护性,在开发时应当合理运用StringBuilder的所有方法,,从而使代码的质量更高,效率更高。