玖叶教程网

前端编程开发入门

Java路径-15-Java的StringBuffer类

1 StringBuffer类

基本介绍:StringBuffer 是 Java 标准库中的一个类,用于处理可变的字符串序列。它与不可变的字符串 String 类似,但是 StringBuffer 允许对字符串内容进行修改和操作,适用于需要频繁拼接和修改字符串的情况,尤其在多线程环境下推荐使用线程安全版本的 StringBuilder。

  • 可变性: StringBuffer 对象的内容可以被修改,包括添加、插入、删除和替换字符等操作。
  • 线程安全性: StringBuffer 是线程安全的,即多个线程同时对一个 StringBuffer 进行操作时,不会出现数据不一致的问题。这是通过使用同步机制来实现的,但这也会带来一些性能开销。如果不需要线程安全,推荐使用性能更好的 StringBuilder。
  • 构造方法: StringBuffer 提供了多个构造方法,可以通过字符串、字符数组、初始容量等来初始化。 StringBuffer() : 构造一个其中不带字符的字符串缓冲区,其初始容量为 16 个字符。(容量是可以自动扩容的) StringBuffer(int capacity) :构造一个不带字符,但具有指定初始容量的字符串缓冲区。 StringBuffer(String str) :构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容。该字符串的初始容量为 16 加上字符串参数的长度。
  • 常用方法: StringBuffer 提供了一系列的方法用于字符串操作,包括:

append(String str):将指定的字符串追加到当前StringBuffer对象的末尾。 insert(int offset, String str):在指定的位置插入字符串。 delete(int start, int end):删除指定位置范围内的字符。 replace(int start, int end, String str):用指定的字符串替换指定位置范围内的字符。 reverse():反转StringBuffer对象中的字符顺序。 toString():将StringBuffer对象转换为String对象。

  • 性能: 由于 StringBuffer 使用了同步机制以实现线程安全,因此在单线程环境中,性能可能比 StringBuilder 差一些。如果不需要线程安全,并且在单线程环境下频繁修改字符串内容,推荐使用 StringBuilder

2 StringBuilder类

StringBuilder类可以理解为一个字符串缓冲区,它提供一个可变的字符序列,可以在该序列上进行修改操作,比如追加,插入,删除和替换等。与String类不同的是,String类的修改操作每次都会创建一个新的字符串对象,而StringBuilder类的修改操作都是在原有的字符序列上进行的,不会创建新的对象,因此在频繁进行字符串操作时,StringBuilder类的效率比String类高。

StringBuilder类是一个可变的字符串,允许进行多次修改而不创建新的String对象。它是AbstractStringBuilder类的子类,实现了CharSequence接口和java.io.Serializable接口。

该类定义了四个构造函数,分别为不带参数的构造函数、指定初始容量的构造函数、包含CharSequence的构造函数和包含String的构造函数。其中,不带参数的构造函数会创建一个长度为16的StringBuilder对象。指定初始容量的构造函数会根据参数capacity创建一个StringBuilder对象。包含CharSequence的构造函数和包含String的构造函数会创建一个容量为参数长度加16的StringBuilder对象,并将参数序列追加到StringBuilder对象末尾。

3 StringBuffer常见方法

![[Pasted image 20240713155257.png]]

测试代码

public static void main(String[] args) {  
    StringBuffer s1=new StringBuffer("abcd1234!?,;");  
    StringBuffer s2=new StringBuffer("987654321987654");  
    StringBuffer s3=new StringBuffer("987654321");  
    System.out.println("↓↓↓StringBuffer类的一些常用方法如下↓↓↓");  
    System.out.println("-----------------------------------------------------");  
    System.out.println("字符串s1的长度为:" + s1.length());//返回字符串的实际长度  
    System.out.println("-----------------------------------------------------");  
    System.out.println("字符串s1所占容器的大小为:" + s1.capacity());//返回字符串所占容器的总大小  
    System.out.println("-----------------------------------------------------");  
    System.out.println("获取字符串s1中第2个位置的字符:" + s1.charAt(2));  
    System.out.println("-----------------------------------------------------");  
    System.out.println("子字符串'654'第一次出现在字符串s2中的索引为:" + s2.indexOf("654"));  
    System.out.println("从指定的索引6开始搜索,返回子字符串'654'第一次出现在字符串s2中的索引:" + s2.indexOf("654",6));  
    System.out.println("-----------------------------------------------------");  
    System.out.println("子字符串'987'最后一次出现在字符串s2中的索引为:" + s2.lastIndexOf("987"));  
    System.out.println("从指定的索引5开始反向搜索,返回字符串'87'在字符串s2中最后一次出现的索引:" + s2.lastIndexOf("87",5));  
    System.out.println("-----------------------------------------------------");  
    s1.append('x');//在字符串s1的末尾添加字符'c'  
    s1.append("Java");//在字符串s1的末尾添加字符串"Java"  
    System.out.println("修改后的字符串s1为:" + s1);  
    System.out.println("-----------------------------------------------------");  
    s1.insert(4,"abcd");//在第4个位置插入字符串"abcd"  
    System.out.println("修改后的字符串s1为:" + s1);  
    System.out.println("-----------------------------------------------------");  
    s1.deleteCharAt(1);//删除字符串s1中第一个位置的字符  
    s1.delete(2,5);//删除字符串s1中第2到第4个位置的字符  
    System.out.println("修改后的字符串s1为:" + s1);  
    System.out.println("-----------------------------------------------------");  
    s1.replace(4,8,"5678");//将字符串s1中第4到第7个位置的字符串修改为"5678"  
    System.out.println("修改后的字符串s1为:" + s1);  
    System.out.println("-----------------------------------------------------");  
    s1.setCharAt(1,'b');//将字符串s1中第一个位置的字符修改为'b'  
    System.out.println("修改后的字符串s1为:" + s1);  
    System.out.println("-----------------------------------------------------");  
    s2.reverse();//将字符串s2反转  
    System.out.println("修改后的字符串s2为:" + s2);  
    System.out.println("-----------------------------------------------------");  
    System.out.println("截取字符串s1从第4个位置开始到结尾:" + s1.substring(4));  
    System.out.println("-----------------------------------------------------");  
    System.out.println("截取字符串s1从第4个位置开始到第7个位置结尾:" + s1.substring(4,8));  
    System.out.println("-----------------------------------------------------");  
    System.out.println("获取s1的变量类型:" + s1.getClass().getName());  
    System.out.println("将对象信息转化为字符串:" + s2.toString());  
}

输出结果:

↓↓↓StringBuffer类的一些常用方法如下↓↓↓
-----------------------------------------------------
字符串s1的长度为:12
-----------------------------------------------------
字符串s1所占容器的大小为:28
-----------------------------------------------------
获取字符串s1中第2个位置的字符:c
-----------------------------------------------------
子字符串'654'第一次出现在字符串s2中的索引为:3
从指定的索引6开始搜索,返回子字符串'654'第一次出现在字符串s2中的索引:12
-----------------------------------------------------
子字符串'987'最后一次出现在字符串s2中的索引为:9
从指定的索引5开始反向搜索,返回字符串'87'在字符串s2中最后一次出现的索引:1
-----------------------------------------------------
修改后的字符串s1为:abcd1234!?,;xJava
-----------------------------------------------------
修改后的字符串s1为:abcdabcd1234!?,;xJava
-----------------------------------------------------
修改后的字符串s1为:accd1234!?,;xJava
-----------------------------------------------------
修改后的字符串s1为:accd5678!?,;xJava
-----------------------------------------------------
修改后的字符串s1为:abcd5678!?,;xJava
-----------------------------------------------------
修改后的字符串s2为:456789123456789
-----------------------------------------------------
截取字符串s1从第4个位置开始到结尾:5678!?,;xJava
-----------------------------------------------------
截取字符串s1从第4个位置开始到第7个位置结尾:5678
-----------------------------------------------------
获取s1的变量类型:java.lang.StringBuffer
将对象信息转化为字符串:456789123456789

4 String、StringBuffer、StringBulider区别

(1)String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上是更改地址,效率比较低

  • private final char value[];,放在常量池中

(2)StringBuffer保存的是字符串变量,里面的值可以更改,每次更新实际上可以更细内容,不用每次更新地址,效率比较高

  • char[] value;,放在堆中

(3)String与StringBuffer相互转换

public class StringAndStringBuffer {
    public static void main(String[] args) {
        //看 String-->StringBuffer
        String str = "hello";
        //方式1
        // 这里只是把str传入到StringBuffer的构造器中,对原来的str没有影响
        StringBuffer stringBuffer = new StringBuffer(str);

        //方式2
        //使用append方法
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1 = stringBuffer1.append(str);

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

        //方式1:使用StringBuffer提供的toString方法
        String s = stringBuffer3.toString();

        //方式2:使用构造器来搞定
        String s1 = new String(stringBuffer3);
    }
}

(4)StringBuffer和StringBuilder非常相似,他们都代表可变的字符序列,并且方法也一样

(5)String:不可变字符序列,效率低,但是它的复用率高

(6)StringBuffer:可变字符序列,效率高,效率较高(增删改查),线程安全

(7)StringBuilder:可变字符序列,效率最高,线程不安全

(8)String使用注意说明:

  • stirng s = "a";//创建了一个字符串
  • s +="b";//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+"b"也就是ab
  • 如果多次执行,就会有大量的副本留在常量池中,降低效率,影响程序的性能

故:如果要对String做大量的修改,就不使用String类

5 总结

  1. 如果字符串存在大量的修改操作,一般使用 StringBufferStringBuilder
  2. 如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder
  3. 如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer
  4. 如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言