|   |  - 不可变的字符序列
 - 在 jdk1.8,我们底层用 char [ ] 存储
 - 在 jdk 17,我们底层用 byte  [ ] 存储 
 
  | 
|   |  - 可变的字符序列,线程安全的(synchronized),效率低
 - 在 jdk1.8,我们底层用 char [ ] 存储
 - 在 jdk 17,我们底层用 byte  [ ] 存储 
 
  | 
|   |  - 可变的字符序列,jdk5.0新增的,线程不安全的,效率高
 - 在 jdk1.8,我们底层用 char [ ] 存储
 - 在 jdk 17,我们底层用 byte  [ ] 存储 
 
  | 
 1、那么在开发当中我们应该到底怎么选择呢?
 - 首先看是不是一个多线程问题。
 - 不是多线程问题,就用StringBuilder
 - 因为只有多个线程操作共享数据的时候,我们才会考虑用StringBuffer
 - 否则不是多线程,或者不存在多线程的安全问题,我们都建议用StringBuilder。
 
 2、jdk8源码分析String
 - String str = new String();                    //char[ ] value = new char[0];
 - String str1 = new String("abc")         //char[ ]  value = new char[ ]{  'a',  'b',  'c'  };
 
 
  3、jdk8源码分析StringBuffer
 - StringBuffer sb1 = new StringBuffer();        //char[ ] value = new char[16];   底层创建了一个长度是16的数组。
 - sb1.append('a');    //value[0] = 'a';
 - sb1.append('b')     //value[1] = 'b';
 
 
  package stringdemo;public class StringBufferTest {public static void main(String[] args) {StringBuffer sb = new StringBuffer();System.out.println(sb.capacity());//16}
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\lib\idea_rt.jar=34469:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\Exception stringdemo.StringBufferTest
16Process finished with exit code 0
 - StringBuffer   sb2 = new StringBuffer(“abc”);//char[ ] value= new char["abc".length()+16]
 
 
 package stringdemo;public class StringBufferTest {public static void main(String[] args) {StringBuffer sb1 = new StringBuffer("abc");System.out.println(sb1.capacity());//3+16=19}
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\lib\idea_rt.jar=35502:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\Exception stringdemo.StringBufferTest
19Process finished with exit code 0
  3.1、扩容问题
 - 如果要添加的数据底层数组盛不下了,那就需要扩容底层的数组。
 - 默认情况下,扩容为原来容量的2倍+2,同时将原有数组中的元素赋值到新的数组中。
 - new StringBuilder();     创建的时候是不会扩容的,容量是(字符串参数的长度 加上16)。
 
 package stringdemo;public class StringBufferTest {public static void main(String[] args) {//new  StringBuffer();创建的时候是不会扩容的StringBuffer sb1 = new StringBuffer("66666666666666666666666666666666666666666666666666666666");System.out.println(sb1.length());//56System.out.println(sb1.capacity());//56+16=72}
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\lib\idea_rt.jar=37260:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\Exception stringdemo.StringBufferTest
56
72Process finished with exit code 0
 - sb1.append();的时候,追加的时候才会发生扩容。超出(字符串参数的长度+16)的时候才会发生扩容。
 
 
public class StringBufferTest {public static void main(String[] args) {StringBuffer sb1 = new StringBuffer("44444444");//new创建的时候不会发生扩容System.out.println(sb1.length());//8System.out.println(sb1.capacity());//8+16=24System.out.println("===================");sb1.append("44444444");System.out.println(sb1.length());//16System.out.println(sb1.capacity());//24System.out.println("===================");sb1.append("44444444");System.out.println(sb1.length());//24System.out.println(sb1.capacity());//24 这个时候StringBuffer的容量已经满,再append就会扩容System.out.println("===================");sb1.append("4");System.out.println(sb1.length());//25System.out.println(sb1.capacity());//24*2+2=50   扩容为原来容量的2倍+2}
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\lib\idea_rt.jar=37603:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\jdk8 StringBufferTest
8
24
===================
16
24
===================
24
24
===================
25
50Process finished with exit code 0
 
  
  3.2、指导意见
 - 开发中建议大家使用:StringBuffer(int capacity),为了避免扩容,一开始建议使用带参数的构造器,效率会高一些。
 
 4、StringBuffer类常用方法
  - StringBuffer append(xxx):
 
  |  - 提供了很多的append()方法,用于进行字符串拼接
 
  | 
 - StringBuffer  delete(int start,int end):
 
  |   | 
 - StringBuffer  replace(int start,int end,String str):
 
  |   | 
 - StringBuffer insert(int offset,xxx):
 
  |   | 
|   |   | 
 - 当append和insert时,如果原来value数组长度不够,可扩容。
 - 如上这些方法支持方法链操作
 
  总结 |   |   | 
|   |  - delete(int start,int end)
 
  | 
|   |  - setCharAt(int n,char ch)        /     replace(int start,int end,String str)
 
  | 
|   |   | 
|   |   | 
|   |   | 
|   |  - for() + charAt()     /    toString()
 
  | 
 
 
 5、对比String、StringBuffer、StringBuilder三者的效率:
 - 从高到低排列:StringBuilder > StringBuffer > String
 
 public class Efficiency {public static void main(String[] args) {long startTime = 0L;long endTime = 0L;String text = "";StringBuffer buffer = new StringBuffer("");StringBuilder builder = new StringBuilder("");startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {buffer.append(String.valueOf(i));}endTime = System.currentTimeMillis();System.out.println("StringBuffer的执行时间:" + (endTime - startTime));startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {builder.append(String.valueOf(i));}endTime = System.currentTimeMillis();System.out.println("StringBuilder的执行时间:" + (endTime - startTime));startTime = System.currentTimeMillis();for (int i = 0; i < 20000; i++) {text = text + i;}endTime = System.currentTimeMillis();System.out.println("String的执行时间:" + (endTime - startTime));}
}
D:\Java\jdk-17\bin\java.exe "-javaagent:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\lib\idea_rt.jar=18779:D:\BaiduNetdiskDownload\IntelliJ IDEA 2023.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\JavaSenior\out\production\jdk8 Efficiency
StringBuffer的执行时间:5
StringBuilder的执行时间:3
String的执行时间:210Process finished with exit code 0