1. String、StringBuffer 和 StringBuilder 三者的异同?
String:不可变的字符序列,底层使用 char[] 存储;
StringBuffer:可变的字符序列,线程安全,效率低;底层使用 char[] 存储;
StringBuilder:可变的字符序列,jdk5.0 新增的,线程不安全,效率高,不考虑线程安全问题时首选该类(比如单线程),底层也是使用 char[] 存储。
2. 源码分析
String:
String str1 = new String(); // char[] value = new char[0];
String str2 = new String("abc"); // char[] value = new char[]{'a', 'b', 'c'};
StringBuffer:
StringBuffer sb1 = new StringBuffer(); // char[] value = new char[16]; 底层创建了一个长度为16的数组
sb1.append('a'); // value[0] = 'a';
sb1.append('b'); // value[1] = 'b';
sb1.append('c'); // value[2] = 'c';
StringBuffer sb2 = new StringBuffer("abc"); // char[] value = new char["abc".length() + 16];
StringBuffer sb3 = new StringBuffer(10); // char[] value = new char[10];
StringBuilder:
和 StringBuffer 一样都是继承自 AbstractStringBuilder 抽象类,除了刚才提到的区别之外,设计是一样的。
- 注意: sb2.length() 是 3。知道了底层是16的数组反而会误导你;
- 扩容问题:如果要添加的数据底层数组盛放不下了,那就需要扩充底层数组。默认情况下, 扩容为原来容量的2倍 + 2,同时将原有数组中的元素使用
Arrays.copyOf()
方法复制到新的数组中; - 指导意义:开发中建议使用 StringBuffer(int capacity) 或 StringBuilder(int capacity) 预先指定合适的容量,避免频扩容。
网友评论