Java 中的StringBuffer类和StringBuilder类(4千字详解)

一、StringBuffer 类

1. 基本概念

(1)StringBuffer 类对象代表一个可变的字符序列,可以对字符串内容进行增删等操作;
(2)StringBuffer 类中的很多方法与 String 类中的方法相同,但它是可变长度的;
(3)StringBuffer 类对象是一个容器。

  • 使用细节:

1. StringBuffer 类的直接父类 是 AbstractStringBuilder 类。
2. StringBuffer 实现了 Serializable 接口,代表了 StringBuffer 类的对象可以串行化【即可以进行网络编程】。
3. 在父类 AbstractStringBuilder 中包含属性 char[] value,没有 final 修饰(与 String 类不同),因此该 value 数组存储字符串的位置在堆内存中,而不是在方法区的常量池中。
4. StringBuffer 类是一个 final 类,不能被继承。
5. 因为StringBuffer 类对象的字符序列是存储在 char[] value 属性中的,所以在改变字符序列时(增加/删除), 不用每次都更换对象地址(即不是每次创建新对象), 因此其效率高于 String 类。
6. StringBuffer 类实现了多线程同步(即它是线程安全的)。

2. String 类和 StringBuffer 类的区别

(1)String 类对象保存的是字符串常量(在常量池中),里面的字符序列不能被更改,每次对字符串的改变,都是在常量池中创建了一个新的字符串(对象/空间/地址),而原有的字符串依然存在。

(2)StringBuffer 类对象是一个容积可变的容器,它用来保存字符序列(在堆内存中),但其保存的字符序列可以改变,每次对字符串的改变,都是在原有的字符串上进行操作,而不用新创建一个字符串(对象/空间/地址),原有的字符串不再存在了。

  • String对象 和 StringBuffer 对象的相互转换

    // String ——> StringBuffer
    String str = "hello tom";
    
    // 方式1: 使用 StringBuffer 类的构造器
    // 注意: 返回的才是StringBuffer对象,对str 本身没有影响
    StringBuffer stringBuffer = new StringBuffer(str);
    
    // 方式2: 使用 StringBuffer 类的 append 方法
    StringBuffer stringBuffer1 = new StringBuffer();
    stringBuffer1 = stringBuffer1.append(str);

    // StringBuffer --> String
    StringBuffer stringBuffer3 = new StringBuffer("lineryue");

    // 方式1: 使用 String 类的构造器
    String s = new String(stringBuffer3);
    
    // 方式1: 使用 StringBuffer 类的 toString 方法
    String s1 = stringBuffer3.toString();
        

3. StringBuffer 类常用方法

  • 如下表:
方法 功能
public StringBuffer append(String str) 将指定的字符串追加到此字符序列。
public StringBuffer delete(int start, int end) 移除此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。如果 start 等于 end,则不发生任何更改。
public StringBuffer replace(int start,int end,String str) 使用给定 String 中的字符替换此序列的子字符串中的字符。该子字符串从指定的 start 处开始,一直到索引 end - 1 处的字符,如果不存在这种字符,则一直到序列尾部。先将子字符串中的字符移除,然后将指定的 String 插入 start。(如果需要,序列将延长以适应指定的字符串。)
public int indexOf(String str) 返回第一次出现的指定子字符串在该字符串中的索引。
public StringBuffer insert(int offset, String str) 将字符串插入此字符序列中。 按顺序将 String 参数中的字符插入此序列中的指定位置,将该位置处原来的字符向后移,此序列将增加该参数的长度。如果 str 为 null,则向此序列中追加 4 个字符 “null”。
public char charAt(int index) 返回此序列中指定索引处的 char 值。第一个 char 值在索引 0 处,第二个在索引 1 处,依此类推,这类似于数组索引。 index 参数必须大于等于 0,且小于此序列的长度。
public int length() 返回长度(字符数)不是容量。
  • 代码演示:

public class StringBufferMethod {
    
    
    public static void main(String[] args) {
    
    

        StringBuffer s = new StringBuffer("hello");

        // 增
        s.append(','); // "hello,"
        s.append("张三丰");// "hello,张三丰"
        s.append("赵敏").append(100).append(true).append(10.5);// "hello,张三丰赵敏100true10.5"
        System.out.println(s);// "hello,张三丰赵敏100true10.5"

        // 删
        /*
         * 删除索引为 >= start && < end 处的字符
         * 解读: 删除 11~14的字符 [11, 14)
         */
        s.delete(11, 14);
        System.out.println(s);// "hello,张三丰赵敏true10.5"

        // 改
        // 解读,使用 周芷若 替换 索引9-11的字符 [9,11)
        s.replace(9, 11, "周芷若");
        System.out.println(s);// "hello,张三丰周芷若true10.5"

        // 查
        // 查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
        int indexOf = s.indexOf("张三丰");
        System.out.println(indexOf);// 6

        // 插
        // 解读,在索引为9的位置插入 "赵敏",原来索引为9的内容自动后移
        s.insert(9, "赵敏");
        System.out.println(s);// "hello,张三丰赵敏周芷若true10.5"

        // 长度
        // 返回字符的个数,与容量无关
        System.out.println(s.length());// 22
        System.out.println(s);

		// charAt()
        // 返回此序列中指定索引处的 char 值,与容量无关
        System.out.println(s.charAt(0);// h
        
    }
}

二、StringBuilder 类

1. 基本概念

(1)StringBuilder 类保存了一个可变的字符序列。此类提供了一个与 StringBuffer 类兼容的API。该类被设计用作 StringBuffer 类的一个简易替换,用在字符串缓冲区被单个线程使用的时候。
(2) StringBuilder 类不保证同步(即不是线程安全的),但它要比StringBuffer 类的速度快,在单线程中,优先使用该类。

  • 使用细节:

1. StringBuilder 类的直接父类 是 AbstractStringBuilder 类。
2. StringBuilder 实现了 Serializable 接口,代表了 StringBuffer 类的对象可以串行化【即可以进行网络编程】。
3. 在父类 AbstractStringBuilder 中包含属性 char[] value,没有 final 修饰(与 String 类不同),因此该 value 数组存储字符串的位置在堆内存中,而不是在方法区的常量池中。
4. StringBuilder 类是一个 final 类,不能被继承。
5. 因为StringBuilder 类对象的字符序列是存储在 char[] value 属性中的,所以在改变字符序列时(增加/删除), 不用每次都更换对象地址(即不是每次创建新对象), 因此其效率高于 String 类。
6. StringBuilder 类没有实现多线程同步(即它不是线程安全的)。

2. String、StringBuffer 和 StringBuilder 的比较

  • 比较如下:
    在这里插入图片描述
  • 代码演示:

public class StringVsStringBufferVsStringBuilder {
    
    
    public static void main(String[] args) {
    
    

        long startTime = 0L;
        long endTime = 0L;
        StringBuffer buffer = new StringBuffer("");

        startTime = System.currentTimeMillis();

        // StringBuffer 拼接 20000次
        for (int i = 0; i < 80000; i++) {
    
    
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:" + (endTime - startTime));


        StringBuilder builder = new StringBuilder("");
        startTime = System.currentTimeMillis();

        // StringBuilder 拼接 20000次
        for (int i = 0; i < 80000; i++) {
    
    
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:" + (endTime - startTime));


        String text = "";
        startTime = System.currentTimeMillis();

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

    }
}
  • String、StringBuffer 和 StringBuilder 的选择
    在这里插入图片描述

总结

  • 本文是小白博主在学习B站韩顺平老师的Java网课时整理总结的学习笔记,在这里感谢韩顺平老师的网课,如有有兴趣的小伙伴也可以去看看。
  • 本文详细解释了 StringBuffer和StringBuilder类 的概念与使用,并讲解了 StringBuffer和StringBuilder类还有String类 相互转换的方法和区别,还举了很多例子,希望小伙伴们看后能有所收获!
  • 最后,如果本文有什么错漏的地方,欢迎大家批评指正!一起加油!!我们下一篇博文见吧!

猜你喜欢

转载自blog.csdn.net/weixin_45395059/article/details/125773239