首页 > 编程笔记

Java StringBuffer类用法详解

前面介绍了 String 类的使用,在实际开发中使用 String 类会存在一个问题,String 对象一旦创建,其值是不能修改的,如果要修改,会重新开辟内存空间来存储修改之后的对象,即修改了 String 的引用。

理由很简单,String 的底层是用数组来存值的,数组长度不可改变这一特性导致了上述问题,所以如果开发中需要对某个字符串进行频繁的修改,使用 String 就不合适了,会造成内存空间的浪费。

如何解决这个问题呢?可以使用 StringBuffer 类来解决。

StringBuffer 和 String 类似,底层也是用一个数组来存储字符串的值,并且数组的默认长度为 16,即一个空的 StringBuffer 对象,数组长度为 16:
@HotSpotIntrinsicCandidate
public StringBuffer{
    super(16);
}

当我们调用有参构造创建一个 StringBuffer 对象时,数组长度就不是 16了,而是根据当前对象的值来决定数组的长度,“值的长度+16”作为数组的长度:
@HotSpotIntrinsicCandidate
public StringBuffer(String s){
    super(str.length()+16);
    append(str);
}

所以一个 StringBuffer 创建完成之后,有 16 字节的空间可以对其值进行修改。如果修改的值范围超出了 16 字节,则调用 ensureCapacityInternal() 方法继续对底层数组进行扩容,并且保持引用不变,ensureCapacityInternal()方法的具体实现如下:
private void ensureCapacityInternal(int minimumCapacity) {
    // overflow-conscious code
    int oldCapacity = value.length >> coder;
    if (minimumCapacity - oldCapacity > 0) {
        value = Arrays.copyOf(value, newCapacity(minimumCapacity) << coder);
    }
}

以上就是 StringBuffer 创建及修改的底层原理。接下来,我们来通过代码完成对 StringBuffer 的使用,StringBuffer 常用方法如下表所示。

表:StringBuffer常用方法
方法 描述
public StringBuffer() 无参构造,创建一个空的StringBuffer
public StringBuffer(String str) 有参构造
public synchronized int length() 返回 StringBuffer 的长度
public synchronized char charAt(int index) 返回字符串中指定位置的字符
public synchronized StringBuffer append(String str) 追加字符
public synchronized StringBuffer delete(int start, int end) 删除指定区间内的字符
public synchronized StringBuffer deleteCharAt(int index) 删除指定位置的字符
public synchronized StringBuffer replace(int start, int end, String str) 将指定区间内的值替换为 str
public synchronized String substring(int start) 裁取字符串从指定位責开始到结尾
public synchronized String substring(int start, int end) 截取字符串从指定位置开始到指定位置结束
public synchronized StringBuffer insert(int offset, String str) 向指定位置插入 str
public int indexOf(String str) 从头开始童找指定字符的位直
public int indexOf(String str, int fromlndex) 从指定的位置开始查找指定字符的位置
public synchronized StringBuffer reverse() 进行反转
public synchronized String toString() 返回 StringBuffer 对应的 String

举个简单的例子:
public class StringBufferTest {
   public static void main(String[] args) {
      StringBuffer stringBuffer = new StringBuffer();
      System.out.println("StringBuffer:"+stringBuffer);
      System.out.println("StringBuffer的长度:"+stringBuffer.length());
      stringBuffer = new StringBuffer("Hello World");
      System.out.println("StringBuffer:"+stringBuffer);
      System.out.println("下标为2的字符是:"+stringBuffer.charAt(2));
      stringBuffer = stringBuffer.append("Java");
      System.out.println("append之后的StringBuffer:"+stringBuffer);
      stringBuffer = stringBuffer.delete(3, 6);
      System.out.println("delete之后的StringBuffer:"+stringBuffer);
      stringBuffer = stringBuffer.deleteCharAt(3);
      System.out.println("deleteCharAt之后的StringBuffer:"+stringBuffer);
      stringBuffer = stringBuffer.replace(2,3,"StringBuffer");
      System.out.println("replace之后的StringBuffer:"+stringBuffer);
      String str = stringBuffer.substring(2);
      System.out.println("substring之后的String:"+str);
      str = stringBuffer.substring(2,8);
      System.out.println("substring之后的String:"+str);
      stringBuffer = stringBuffer.insert(6,"six");
      System.out.println("insert之后的StringBuffer:"+stringBuffer);
      System.out.println("e的下标是:"+stringBuffer.indexOf("e"));
      System.out.println("下标6之后的e的下标是:"+stringBuffer.indexOf("e",6));
      stringBuffer = stringBuffer.reverse();
      System.out.println("reverse之后的StringBuffer:"+stringBuffer);
      str = stringBuffer.toString();
      System.out.println("StringBuffer对应的String:"+str);
   }
}
运行结果为:

StringBuffer:
StringBuffer的长度:0
StringBuffer:Hello World
下标为2的字符是:l
append之后的StringBuffer:Hello WorldJava
delete之后的StringBuffer:HelWorldJava
deleteCharAt之后的StringBuffer:Helorldjava
replace之后的StringBuffer:HeStringBufferorldJava
substring之后的String:StringBufferorldJava
substring之后的String:String
insert之后的StringBuffer:HeStrisixngBufferorldJava
e的下标是:1
下标6之后的e的下标是:15
reverse之后的StringBuffer:avaJdlroreffuBgnxisirtSeH
StringBuffer对应的String:avaJdlroreffuBgnxisirtSeH

推荐阅读

副业交流群 关注微信公众号,加入副业交流群,学习变现经验,交流各种打法。