java中的StringBuffer类
本文主要讲述StringBuffer类的重要细节
老韩介绍StringBuffer类
示例代码如下:
1 public class StringBufferTest { 2 public static void main(String[] args) { 3 // private final char value[]; 4 String s1 = "hello"; 5 System.out.println(s1.hashCode()); 6 s1 = s1 + "world"; 7 System.out.println(s1.hashCode()); 8 9 // StringBuffer的效率更高,每次拼接,如果没有超过容量,就直接在末尾添加; 10 // 如果超过容量,则扩容,将原数组的值赋值到新数组,最后在新数组末尾添加,将新数组的地址返回给value 11 // private transient char[] toStringCache; 12 StringBuffer sb1 = new StringBuffer("hello"); 13 System.out.println(sb1.hashCode()); 14 sb1 = sb1.append("world"); 15 System.out.println(sb1.hashCode()); 16 } 17 }
具体内存分布图,如下图所示:
上面两张图片,讲述着String类对象的创建:
String s1 = "hello";
查看常量池中,是否有hello字符串,如果有hello字符串,则返回hello字符串在常量池中的地址,给s1;如果没有hello字符串,则在常量池中开辟存储空间存放hello字符串,返回hello字符串的地址,给s1。
s1 = s1 + "world";
注意:并不是在hello字符串末尾添加world,而是另外开辟存储空间,复制hello字符串,在其末尾添加world,将新字符串的地址返回给s1。付出的代价很大,浪费时间。
上面两张图片,讲述着StringBuffer类对象的创建:
StringBuffer sb1 = new StringBuffer("hello");
首先加载StringBuffer类,在堆中开辟存储空间,用于存储StringBuffer类的对象,接着在堆中开辟存储空间,用于存储hello字符串数组,将hello字符串数组的地址返回给StringBuffer类的成员toStringCache。
sb1 = sb1.append("world");
如果添加后的字符串长度,没有超过限制容量,直接在toStringBuffer指向的存储空间的末尾添加world;如果超过限制长度,则需要扩容【扩容机制】,开辟新数组的存储空间,将原数组的值赋值到新数组中,并且在其末尾添加world,最后将新数组的地址返回给toStringBuffer。无需每次都开辟新的存储空间,存储新的字符串。
运行结果如下:
99162322 -1524582912 460141958 460141958
可见,String类的 s1 引用指向的地址不相同,而StringBuffer类的引用 sb1 指向的地址相同。
测试题1,示例代码如下:
1 public class StringBufferTest { 2 public static void main(String[] args) { 3 // 输入商品名称 商品价格 ,要求打印效果示例: 4 // 商品名 商品价格 5 // 手机 123,567.59【整数部分,3位一个小数点】 6 // StringBuffer buffer = new StringBuffer("123567.59"); 7 // int index = buffer.indexOf("."); 8 // buffer = buffer.insert(index - 3, ","); 9 // System.out.println(buffer); 10 11 Scanner scan = new Scanner(System.in); 12 String price = scan.next(); 13 StringBuffer sb = new StringBuffer(price); 14 // lastIndexOf(),返回指定字符串在原字符串中的位置,若没有找到则返回-1. 15 for(int i = sb.lastIndexOf(".") - 3;i > 0;i -= 3){ 16 // insert(),在指定索引处,插入目标字符串,返回新字符串的地址. 17 sb = sb.insert(i,","); 18 } 19 System.out.println(sb); 20 } 21 }
String类,StringBuffer类,StringBuilder类的比较: