面试题答案
一键面试StringBuilder链式调用方法底层实现原理
- 内存分配
StringBuilder
内部维护了一个字符数组value
用于存储字符串内容。初始时,若未指定容量,默认容量为16。当通过链式调用不断追加字符或字符串时,如果当前value
数组的容量不足以容纳新的内容,会进行扩容。- 扩容机制:新容量为当前容量的2倍加2。例如,初始容量为16,第一次扩容后容量为
16 * 2 + 2 = 34
。扩容时会创建一个新的更大的字符数组,将原数组内容复制到新数组中。
- 方法执行流程
- 以
append
方法为例,链式调用如new StringBuilder().append("a").append("b")
。 - 当调用第一个
append("a")
时,首先检查当前value
数组容量是否足够存储"a"
。如果足够,直接将"a"
的字符按顺序放入value
数组中,并更新数组中字符的计数变量count
。如果容量不足,则进行扩容,然后再放入字符。 - 接着调用第二个
append("b")
,同样检查容量,若不足再次扩容,然后将"b"
放入value
数组,更新count
。 - 链式调用的关键在于
append
等方法返回this
,即当前的StringBuilder
对象,这样就可以继续在返回的对象上调用其他方法,实现链式操作。例如:
- 以
public StringBuilder append(String str) {
super.append(str);
return this;
}
基于底层原理的性能优化
- 预估计容量
- 如果能提前知道最终字符串的大致长度,在创建
StringBuilder
对象时指定合适的初始容量。这样可以减少扩容的次数,提高性能。例如,如果预计最终字符串长度为100,创建StringBuilder
时可以使用new StringBuilder(100)
。
- 如果能提前知道最终字符串的大致长度,在创建
- 减少不必要的链式调用
- 避免在链式调用中进行复杂的、重复计算的操作。例如,不要在链式调用的
append
方法参数中每次都进行高开销的计算。如果有复杂计算,提前计算好结果,再进行链式调用。
- 避免在链式调用中进行复杂的、重复计算的操作。例如,不要在链式调用的
- 批量操作替代多次单个操作
- 若要追加多个短字符串,使用
append
方法一次性追加多个字符串,而不是多次单个追加。例如,append("a").append("b").append("c")
可以改为append("abc")
,这样可以减少多次检查容量和可能的扩容操作。
- 若要追加多个短字符串,使用