StringBuffer和StringBuilder

我们之前说到String是不可变的,并且垃圾回收也不会回收常量池中的数据,所以如果在实际开发中,涉及到频繁的字符串操作的话,会十分的占用方法区的内存。所以,我们有了长度可变的另外两个字符串类:StringBuffer和StringBuilder,它们都是可变的。

原因分析:

StringBuffer和StringBuilder底层为byte[],而String为private final byte[],所以StringBuffer可变,String不可变。

  • StringBuffer
public final class StringBuffer
extends Object
implements Serializable,CharSequence

不可被继承,该类拥有四个构造方法:

public StringBuffer()	//构造一个没有字符的字符串缓冲区,初始容量为16个字符。
    
public StringBuffer(int capacity)	//构造一个没有字符的字符串缓冲区和指定的初始容量。
    
public StringBuffer(String str)//构造一个初始化为指定字符串内容的字符串缓冲区。字符串缓冲区的初始容量为16加上字符串参数								//的长度。
    
public StringBuffer(CharSequence seq)//构造一个包含与指定的相同字符的字符串缓冲区CharSequence 。 字符串缓冲区的初始									 //容量为16加上CharSequence参数的长度。 

例:例举常用方法,追加、删除、插入、逆置......

package com.dh.stringbuffer;

public class StringBufferDemo01 {

    public static void main(String[] args) {

        StringBuffer stringBuffer = new StringBuffer();
        //输出容量
        int capacity = stringBuffer.capacity();
        System.out.println(capacity);   //输出:16

        StringBuffer stringBuffer1 = new StringBuffer(32);
        System.out.println(stringBuffer1.capacity());   //输出:32

        StringBuffer stringBuffer2 = new StringBuffer("hello");
        System.out.println(stringBuffer2.capacity());   //输出:21(16+5)

        System.out.println("原始数据:");
        System.out.println(stringBuffer2);

        //StringBuffer是可变的,可以在原字符串中追加内容
        //追加的内容可以是基本数据类型、字符串、对象、数组等
        //演示stringBuffer2的追加,stringBuffer和stringBuffer1同
        System.out.println("===============================");
        System.out.println("追加数据:");
        stringBuffer2.append(1);
        stringBuffer2.append('1');
        stringBuffer2.append(1.1);
        stringBuffer2.append("world");
        //该对象会自动调用Object的toString(),可在类中重写
        stringBuffer2.append(new StringBufferDemo01());
        char[] chars = {'a','b'};
        stringBuffer2.append(chars);

        System.out.println(stringBuffer2);

        System.out.println("===============================");
        System.out.println("删除数据:");
        //也可删除
        stringBuffer2.delete(1,3);  //字符串下标,[)
        System.out.println(stringBuffer2);

        System.out.println("===============================");
        System.out.println("插入数据:");
        //也可插入
        //第一个参数为开始插入的下标,第二个参数为内容,可为其它数据类型
        stringBuffer2.insert(1,"插入的内容");
        System.out.println(stringBuffer2);

        System.out.println("===============================");
        System.out.println("逆置数据:");
        StringBuffer reverse = stringBuffer2.reverse();
        System.out.println(reverse);
    }
}

结果:

16
32
21
原始数据:
hello
===============================
追加数据:
hello111.1worldcom.dh.stringbuffer.StringBufferDemo01@6e8dacdfab
===============================
删除数据:
hlo111.1worldcom.dh.stringbuffer.StringBufferDemo01@6e8dacdfab
===============================
插入数据:
h插入的内容lo111.1worldcom.dh.stringbuffer.StringBufferDemo01@6e8dacdfab
===============================
逆置数据:
bafdcad8e6@10omeDreffuBgnirtS.reffubgnirts.hd.mocdlrow1.111ol容内的入插h

若是想要优化StringBuffer的性能,可以在一开始的时候,设定一个尽可能符合要求的容量,减少扩容次数或者浪费内存的情况

还有其余的方法可查看api文档~

  • StringBuilder
public final class StringBuilder
extends Object
implements Serializable,CharSequence

StringBuilder同StringBuffer的用法。

StringBuffer和StringBuilder的区别

点进去这两个类的源码可以发现,StingBuffer中的方法有synchronized修饰,而StringBuilder中没有,所以StringBuffer是多线程安全的,StringBuilder是线程不安全的。

具体使用哪个,需要结合实际情况,并不是不安全的就一定不好,在某些情况下,虽然存在不安全,但是效率会更高。

posted @ 2021-01-25 16:53  deng-hui  阅读(61)  评论(0编辑  收藏  举报