Java-String

Java-String

1. StringBuilder和StringBuffer的区别

StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,只是 StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。

在单线程程序下,StringBuilder 效率更快,因为它不需要加锁、不具备多线程安全;而 StringBuffer 则每次都需要判断锁,效率相对更低。


2. 扩容策略

StringBuilder 的初始容量可以容纳 16 个字符,当该对象的实体存放的字符的长度大于 16 时,实体容量就自动增加。StringBuilder 对象可以通过 length() 方法获取实体中存放的字符序列长度,通过 capacity() 方法来获取当前实体的实际容量。

StringBuilder(int size) 可以指定分配给该对象的实体的初始容量参数为 size。当该对象的实体存放的字符序列的长度大于 size 个字符时,实体的容量就自动的增加。以便存放所增加的字符。

StringBuilder(String s) 可以指定给对象的实体的初始容量 sizes 的长度 额外再加 16 个字符。当该对象的实体存放的字符序列长度大于 size 个字符时,实体的容量自动的增加,以便存放所增加的字符。

2.1 扩容算法

使用 append() 方法在字符串后面追加东西的时候,如果长度超过了该字符串存储空间大小了就需要进行扩容:构建新的存储空间更大的字符串,将旧的复制过去;

  • 在进行字符串 append() 的时候,会先计算追加后字符串大小;
  • 将追加后的字符串大小传入 ensureCapacityInternal(),由这个方法进行是否扩容的判断;
    • 如果需要扩容就调用 expandCapacity() 进行扩容,尝试将新容量扩为大小变成 当前容量 * 2 + 2
    • if 判断一下,如果容量还是不够,直接扩充到需要的容量大小。