StringBuffer和StringBuild

113 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情

哈喽,大家好!我是Why,一名在读学生,目前刚刚开始进入自己的编程学习生涯。虽然学习起步较晚,但我坚信做了才有0或1的可能。学了一段时间以后也是选择在掘金上分享自己的日常笔记,也希望能够在众多道友的大家庭中打成一片。 本文主要讲解* StringBuffer和StringBuild*,如果大家读后觉得有用的话,还请大家多多支持博主:欢迎 ❤️点赞👍、收藏⭐、留言💬 ✨✨✨个人主页:JinHuan

StringBuffer类

  * 思考:我们在实际的开发中,如果需要进行字符串的频繁拼接,会有什么问题?
  *      因为java中的字符串是不可变的,每一次拼接都会产生新字符串。
  *      这样会占用大量的方法区内存。造成内存空间的浪费。
  *          String s = "abc";
  *          s += "hello";
  *          就以上两行代码,就导致在方法区字符串常量池当中创建了3个对象:
  *              "abc"
  *              "hello"
  *              "abchello"

实例

 /**
  * 如果以后需要进行大量字符串的拼接操作,建议使用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("b");
         stringBuffer.append("d");
         stringBuffer.append(3.14);
         stringBuffer.append(true);
         // append方法底层在进行追加的时候,如果byte数组满了,会自动扩容。
         stringBuffer.append(100L);
 ​
         System.out.println(stringBuffer.toString());
 ​
         // 指定初始化容量的StringBuffer对象(字符串缓冲区对象)
         StringBuffer sb = new StringBuffer(100);
         sb.append("hello");
         sb.append("world");
         sb.append("hello");
         sb.append("kitty");
 ​
         System.out.println(sb);
     }
 }
 ​

String为什么是不可变

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

StringBuilder/StringBuffer为什么是可变

         源代码中,StringBuffer/StringBuilder内部实际上是一个byte[]数组,
         这个byte[]数组没有被final修饰,StringBuffer/StringBuilder的初始化
         容量我记得应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法
         System.arraycopy()...是这样扩容的。所以StringBuilder/StringBuffer
         适合于使用字符串的频繁拼接操作。
实例
 public class StringBufferTest04 {
     public static void main(String[] args) {
 ​
         // 字符串不可变是什么意思?
         // 是说双引号里面的字符串对象一旦创建不可变。
         String s = "abc"; //"abc"放到了字符串常量池当中。"abc"不可变。
 ​
         // s变量是可以指向其它对象的。
         // 字符串不可变不是说以上变量s不可变。说的是"abc"这个对象不可变。
         s = "xyz";//"xyz"放到了字符串常量池当中。"xyz"不可变。
 ​
     }
 }

StringBulider

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);
     }
 }