# StringBuilder
底层属性:value,count。
可变于不可变字符串
String是一个不可变字符串,这里的不可变是指常量池中的对象不变;在引用地址不变的情况下,不能变;
StringBuilder是一个可变字符串,在堆中,它的引用对象地址始终不变,在引用地址不变的情况下,字符串可以变。直接append方法。
编译器对`String`做了特殊处理,使得我们可以直接用`+`拼接字符串。虽然可以直接拼接字符串,但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。
```java
String s = "";
for (int i = 0; i < 1000; i++) {
s = s + "," + i;
}
```
为了能高效拼接字符串,Java标准库提供了`StringBuilder`,它是一个可变对象,可以预分配缓冲区,这样,往`StringBuilder`中新增字符时,不会创建新的临时对象
```java
StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
sb.append(',');
sb.append(i);
}
String s = sb.toString();
```
`StringBuilder`还可以进行链式操作
```java
public class Main {
public static void main(String[] args) {
var sb = new StringBuilder(1024);
sb.append("Mr ")
.append("Bob")
.append("!")
.insert(0, "Hello, ");
System.out.println(sb.toString());
}
}
```
注意:对于普通的字符串`+`操作,并不需要我们将其改写为`StringBuilder`,因为Java编译器在编译时就自动把多个连续的`+`操作编码为`StringConcatFactory`的操作。在运行期,`StringConcatFactory`会自动把字符串连接操作优化为数组复制或者`StringBuilder`操作。
你可能还听说过`StringBuffer`,这是Java早期的一个`StringBuilder`的线程安全版本,它通过同步来保证多个线程操作`StringBuffer`也是安全的,但是同步会带来执行速度的下降。
`StringBuilder`和`StringBuffer`接口完全相同,现在完全没有必要使用`StringBuffer`。
### String,StringBuilder,StringBuffer
String 不可变
StringBuilder和StringBuffer可变。
StringBuilder效率高,线程不安全。
StringBuffer效率低,线程安全。