1、String/StringBuilder/StringBuffer三者的区别
String:不可变的字符序列;jdk1.0;底层使用final char[]
StringBuffer:可变的字符序列;jdk1.0;线程安全的,效率偏低;底层使用char[],这数组来源于AbstractStringBulider
StringBulider:可变的字符序列;jdk1.5;线程不安全,效率高一些;底层使用char[],这数组来源于AbstractStringBulider
线程安全的StringBuffer
原理:
//源码分析
String常见的两种创建对象的情景,
String str=new String();//char[] value =new char[0];直接就是创建一个空的数组
String str1=new String("abc"); //char[] value=new char[]{'a','b','c'};创建数组 同时赋值abc
StringBuffer和StringBulider引用的父类都相同,只是在线程安全问题不同,所以以一个为例,和String进行对比
StringBuffer sb1=new StringBuffer();//空参创建的情况下 Char[] value=new char[16]; 底层创建一个长度16 的数组,也就是分配大小16的存储空间
sb1.append('a');// 相当于value[0]='a';
sb2.append('b');// 相当于value[1]='b'; 在添加过程中 ab两个元素都添加到了同一个数组里面,他们用的是一个数组,反映到StringBuffer就是可变的。
StringBuffer sb2=new StringBuffer("abc"); // 在有参数的情况下 char[] value =new char["abc".length()+16]{'a','b','c'};
问题: sb2.length() ? ----------->3 !不是19(知道太多了!,单纯一点)
Sb1的情况下,一遍遍的append,终究会到达16次,就存在一个扩容的问题:
数组扩容:
默认情况下,扩容为原来数组的2倍再加2,(length左移1位 +2 16*2+2) 。同时将原有的数组中的元素复制到新的数组中 。
StringBulider和StringBuffer可以制定默认的长度,避免append过程中的扩容操作。
2、StringBuffer的常用方法(StringBuilder除了线程不安全外,用法相同)