(二)Java常用类之StringBuffer和StringBuilder | 【奔跑吧!JAVA】

举报
lwq1228 发表于 2021/06/20 16:38:12 2021/06/20
【摘要】 Java常用类之StringBuffer和StringBuilder

1、StringBuffer类

1.1、概述

java.lang.StringBuffer代表可变的字符序列,JDK1.0中声明,可以对字符串内容进行增删,此时不会产生新的对象。
很多方法与String相同。
作为参数传递时,方法内部可以改变值。

1.2、StringBuffer继承关系

StringBuffer继承关系

从StringBuffer类的继承关系可以看到,该类继承自抽象类AbstractStringBuilder,查看AbstractStringBuilder类的源码可知,该类底层使用char型的数组进行数据存储,而且没有final声明,value长度可以不断扩容;通过count属性来记录有效的字符个数。

AbstractStringBuilder源码

1.3、StringBuffer构造器

StringBuffer类不同于String,其对象必须使用构造器生成。有四个构造器:
	StringBuffer():初始容量为16的字符串缓冲区
	StringBuffer(int capacity):构造指定容量的字符串缓冲区
	StringBuffer(String str):将内容初始化为指定字符串内容
	StringBuffer(CharSequence seq):将内容初始化为指定字符序列内容,与StringBuffer(String str)类似
public class StringBufferTest1 {
    public static void main(String[] args) {
        // 无参构造器
        StringBuffer str1 = new StringBuffer();
        System.out.println("无参构造器,初始容量为16的字符串缓冲区:" + str1);

        // 构造指定容量的字符串缓冲区
        StringBuffer str2 = new StringBuffer(32);
        System.out.println("构造指定容量的字符串缓冲区:" + str2);

        // 将内容初始化为指定字符串内容
        StringBuffer st3 = new StringBuffer("Hello World");
        System.out.println("将内容初始化为指定字符串内容:" + st3);
    }
}

1.4、StringBuffer类的常用方法

1.4.1、支持方法链操作的方法

StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转

说明:当append和insert时,如果原来value数组长度不够,可扩容。
以上方法均支持方法链操作。
方法链的原理:(通过以下源码可知,append后又将当前对象作为结果返回,顾可以连续调用StringBuffer方法)
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
public class StringBufferTest2 {
    public static void main(String[] args) {
        StringBuffer str1 = new StringBuffer("Hello World");
        System.out.println(str1);

        // 1、append方法
        str1.append("!!!");
        System.out.println(str1);

        // 2、delete方法
        str1.delete(5, 11);
        System.out.println(str1);

        // 3、replace方法
        str1.replace(5, 8, "...");
        System.out.println(str1);

        // 4、insert方法
        str1.insert(5, " World");
        System.out.println(str1);

        // 5、reverse方法
        str1.reverse();
        System.out.println(str1);
    }
}

1.4.2、其它方法

public int indexOf(String str):获取某个子串的位置
public String substring(int start,int end):截取字符串
public int length():取得字符串长度
public char charAt(int n ):获取某个字符额位置
public void setCharAt(int n ,char ch):修改某个位置的字符
public class StringBufferTest3 {
    public static void main(String[] args) {
        StringBuffer str1 = new StringBuffer("Hello World");
        System.out.println(str1);

        // 1、indexOf方法
        System.out.println("World的开始位置:" + str1.indexOf("World"));

        // 2、substring方法
        System.out.println("截取World子串:" + str1.substring(6, 11));

        // 3、length方法
        System.out.println("获取字符串长度:" + str1.length());

        // 4、charAt方法
        System.out.println("获取索引位置为6的字符:" + str1.charAt(6));

        // 5、setCharAt方法
        str1.setCharAt(6, 'M');
        System.out.println("设置所以位置6的字符为M后的字符串为:" + str1);
    }
}

2、StringBuilder类

2.1、概述

StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样。

1.2、StringBuilder继承关系

StringBuilder继承关系

从StringBuilder类的继承关系可以看到,该类也继承自抽象类AbstractStringBuilder,顾其底层存储方式与StringBuffer一致。

AbstractStringBuilder源码

1.3、StringBuilder构造器

StringBuilder类不同于String,其对象必须使用构造器生成。有四个构造器:
	StringBuilder():初始容量为16的字符串缓冲区
	StringBuilder(int capacity):构造指定容量的字符串缓冲区
	StringBuilder(String str):将内容初始化为指定字符串内容
	StringBuilder(CharSequence seq):将内容初始化为指定字符序列内容,与StringBuilder(String str)类似
public class StringBuilderTest1 {
    public static void main(String[] args) {
        // 无参构造器
        StringBuilder str1 = new StringBuilder();
        System.out.println("无参构造器,初始容量为16的字符串缓冲区:" + str1);

        // 构造指定容量的字符串缓冲区
        StringBuilder str2 = new StringBuilder(32);
        System.out.println("构造指定容量的字符串缓冲区:" + str2);

        // 将内容初始化为指定字符串内容
        StringBuilder st3 = new StringBuilder("Hello World");
        System.out.println("将内容初始化为指定字符串内容:" + st3);
    }
}

1.4、StringBuilder类的常用方法

1.4.1、支持方法链操作的方法

StringBuilder append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuilder delete(int start,int end):删除指定位置的内容
StringBuilder replace(int start, int end, String str):把[start,end)位置替换为str
StringBuilder insert(int offset, xxx):在指定位置插入xxx
StringBuilder reverse() :把当前字符序列逆转

说明:当append和insert时,如果原来value数组长度不够,可扩容。
以上方法均支持方法链操作。
方法链的原理:(通过以下源码可知,append后又将当前对象作为结果返回,顾可以连续调用StringBuilder方法)
    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
public class StringBuilderTest2 {
    public static void main(String[] args) {
        StringBuilder str1 = new StringBuilder("Hello World");
        System.out.println(str1);

        // 1、append方法
        str1.append("!!!");
        System.out.println(str1);

        // 2、delete方法
        str1.delete(5, 11);
        System.out.println(str1);

        // 3、replace方法
        str1.replace(5, 8, "...");
        System.out.println(str1);

        // 4、insert方法
        str1.insert(5, " World");
        System.out.println(str1);

        // 5、reverse方法
        str1.reverse();
        System.out.println(str1);
    }
}

1.4.2、其它方法

public int indexOf(String str):获取某个子串的位置
public String substring(int start,int end):截取字符串
public int length():取得字符串长度
public char charAt(int n ):获取某个字符额位置
public void setCharAt(int n ,char ch):修改某个位置的字符
public class StringBuilderTest3 {
    public static void main(String[] args) {
        StringBuilder str1 = new StringBuilder("Hello World");
        System.out.println(str1);

        // 1、indexOf方法
        System.out.println("World的开始位置:" + str1.indexOf("World"));

        // 2、substring方法
        System.out.println("截取World子串:" + str1.substring(6, 11));

        // 3、length方法
        System.out.println("获取字符串长度:" + str1.length());

        // 4、charAt方法
        System.out.println("获取索引位置为6的字符:" + str1.charAt(6));

        // 5、setCharAt方法
        str1.setCharAt(6, 'M');
        System.out.println("设置所以位置6的字符为M后的字符串为:" + str1);
    }
}

3、String、StringBuffer和StringBuilder对比

String(JDK1.0):不可变的字符序列;底层使用char[]存储
StringBuffer(JDK1.0):可变的字符序列;由源码可知,其所有的方法都使用synchronized,顾是线程安全的,效率低;底层使用char[]存储
StringBuilder(JDK 5.0):可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储

注意:以上三种字符串作为参数传递的话,方法内部String不会改变其值,StringBuffer和StringBuilder会改变其值。

执行效率对比测试:

public class CompareTest {
    public static void main(String[] args) {
        //初始设置
        long startTime;
        long endTime;

        StringBuffer buffer = new StringBuffer();
        //执行次数
        int count = 200000;
        //开始对比
        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            buffer.append(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:" + (endTime - startTime));

        StringBuilder builder = new StringBuilder();
        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            builder.append(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:" + (endTime - startTime));

        String text = "";
        startTime = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String的执行时间:" + (endTime - startTime));
    }
}

测试结果如图:

测试结果

上述是执行200000次字符串拼接操作,三者的执行效率从高到低依次是:StringBuilder > StringBuffer > String

【奔跑吧!JAVA】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/265241

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。