StringBuffer(安全)-StringBuilder(非安全)-字符串拼接

StringBuffer:线程安全

  • 底层实际上是一个byte[]数组;在StringBuffer中存放字符串,时间上是在byte数组中存放;初始化容量为16

在实际的开发中,如果需要进行字符串的频繁拼接,会有什么问题?

 

  • 因为java中的字符串是不可变的,每一次拼接都会产生新字符串。
  • 这样会占用大量的方法区内存。造成内存空间的浪费。
  • String s = "abc";
  • s += "hello";
  • 就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象:
  • "abc" ----"hello"------"abchello"
public class StringBufferTest01 {
    public static void main(String[] args) {
        String s = "";
        // 这样做会给java的方法区字符串常量池带来很大的压力。
        for(int i = 0; i < 100; i++){
            //s += i;
            s = s + i;
            System.out.println(s);
        }
    }
}

 

String为什么是不可变的?

  •     源码中,String类中有一个byte[]数组,这个byte[]数组采用了final修饰,
  •     因为数组一旦创建长度不可变。并且被final修饰的引用一旦指向某个对象之后,不
  •     可再指向其它对象,所以String是不可变的!"abc" 无法变成 "abcd"

StringBuilder/StringBuffer为什么是可变的呢?
    源码中,StringBuffer/StringBuilder内部实际上是一个byte[]数组,
    这个byte[]数组没有被final修饰,StringBuffer/StringBuilder的初始化
    容量应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法System.arraycopy()    
    是这样扩容的。所以StringBuilder/StringBuffer 适合于使用字符串的频繁拼接操作。


进行字符串的拼接操作,建议使用JDK中自带的:

  • java.lang.StringBuffer
  • java.lang.StringBuilder

如何优化StringBuffer的性能?

  • 在创建StringBuffer的时候尽可能给定一个初始化容量。
  • 最好减少底层数组的扩容次数。预估计一下,给一个大一些初始化容量。
  • 关键:给一个合适的初始化容量。可以提高程序的执行效率。
public class StringBufferTest02 {
    public static void main(String[] args) {

        // 创建一个初始化容量为16个byte[] 数组。(字符串缓冲区对象)
        StringBuffer stringBuffer = new StringBuffer();

        // 拼接字符串调用 append()方法。 append是追加的意思。
        stringBuffer.append("a");
        stringBuffer.append(3.14);
        stringBuffer.append(true);
        // append方法底层在进行追加的时候,如果byte数组满了,会自动扩容。
        stringBuffer.append(100L);

        // 指定初始化容量的StringBuffer对象(字符串缓冲区对象)
        StringBuffer sb = new StringBuffer(100);
        sb.append("hello");
        sb.append("world");

        System.out.println(sb);
    }
}

StringBuilder 非线程安全

/*
java.lang.StringBuilder
StringBuffer和StringBuilder的区别:
    StringBuffer中的方法都有:synchronized关键字修饰。表示StringBuffer在多线程环境下运行是安全的。
    StringBuilder中的方法都没有:synchronized关键字修饰,表示StringBuilder在多线程环境下运行是不安全的。

    StringBuffer是线程安全的。
    StringBuilder是非线程安全的。
    
 */
public class StringBuilderTest01 {
    public static void main(String[] args) {

        // 使用StringBuilder也是可以完成字符串的拼接。
        StringBuilder sb = new StringBuilder();
        sb.append(100);
        sb.append(true);
        sb.append("hello");
        sb.append("kitty");
        System.out.println(sb);
    }
}

 

posted @ 2022-05-01 19:12  280887072  阅读(107)  评论(0编辑  收藏  举报