String ,StringBuilder,StringBuffer使用场景
-
String 字符串类,底层是基于char[], 一旦创建长度就固定不变了,适用于字符串不经常增删改的操作的场景。
-
StringBuilder: 基于定长的char[],默认长度是16个,适用于频繁操作(增删改插)字符串的场景,该类是线程不安全的。
-
StringBuffer:基于定长的char[],默认长度是16个,适用于频繁操作(增删改插)字符串的场景,该类是线程安全的。
String的底层原理
public class StringTest {
public static void main(String[] args) {
String str = "abc";//表示在常量池中创建了一个长度是3的char数组
String str2 = "abc";//优先从常量池中找到上面创建的3个长度char数组,当找不到的时候,会重新再常量池创建新的char数组
System.out.println(str==str2);//判断两个对象地址是否相等
System.out.println(str.equals(str2));//判断两个对象值是否相等
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(str3==str4);
System.out.println(str3.equals(str4));
String str5 = "abc" + "d";//优先从常量池查找有没有 "abcd",有就直接用,没有就在常量池创建
str += "d";//字符串拼接,表示在常量池中创建了一个新的char数组,长度是4个,并且将原来数组中的abc复制到了新数组
System.out.println(str);
System.out.println(str == str5);
}
}
StringBuilder的底层原理
public class StringBuilderTest {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();// 创建一个默认16个长度的char[]数组
StringBuilder sb2 = new StringBuilder("abc");// 创建一个19个长度的char[]数组
sb2.append("123456789");
System.out.println(sb2);
}
}
StringBuilder无参构造方法默认在堆中创建16个长度的char[ ]数组,调用的是父类AbstractStringBuilder的构造方法,StringBuilder的有参构造方法在堆中创建参数的长度+16的char[ ]数组,添加的字符串依次从char[]数组前面为空的位置存入。当再次添加的字符串长度超过创建的char[ ]数组长度,就会进行扩容。
public StringBuilder() {
super(16);//默认创建16个长度的char[]数组
}
public StringBuilder(String str) {
super(str.length() + 16);//添加的字符串长度+16
append(str);
}
StringBuffer和StringBuilder扩容机制
当要添加的字符串大于 > 当前字符数组的长度的时候扩容,扩容是: 原来长度*2+2 的方式扩容。
底层源码实现如下:
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;//新数组长度为(原数组长度2倍+2)
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}