java stringbuilder原理_【JAVA每日分享-7】面试题:StringBuilder实现原理?

本文围绕Java的StringBuilder类展开,介绍了其常用方法,如构造、追加、删除、插入等。详细分析了构造方法的不同形式及初始容量设置,重点讲解了append方法的扩容机制和字符拷贝过程,还提及delete、replace等方法的实现,指出其底层通过维护char[]并调用System.arraycopy()构建新数组。

最近群里的小伙伴分享了面试题,我会每天分享一道。

没有点赞、没有评论、没有关爱 ,我都没有写文章的动力了。

开整——

jdk8,idea

看下StringBuilder类的所有方法(alt+7 / ctrl+f12)

a7d608e334dc8ccd50f7ba3dee19da80.png

看起来也没啥复杂的,常用的无非是 构造、追加、删除、插入、获取下标、反转。

构造方法:分为三种,无参构造初始容量16,固定容量,字符长度+16容量

public StringBuilder(){

super(16);

}

public StringBuilder(int capacity){

super(capacity);

}

public StringBuilder(String str){

super(str.length() + 16);

append(str);

}

复制代码append方法:

大致分为两步,先这样。。。然后那样。。。懂了吧,咳咳 缓解下气氛。

判断是否需要扩容(newCapacity = 原长度*2+2)

2)将追加字符串拷贝到char[]中

public AbstractStringBuilder append(String str){

if (str == null)

return appendNull();

int len = str.length();

// 判断容量是否足够,是否需要扩容

ensureCapacityInternal(count + len);

// 将字符从字符串复制到目标字符数组。

str.getChars(0, len, value, count);

count += len;

return this;

}

private void ensureCapacityInternal(int minimumCapacity){

// 新字符串长度大于原字符串长度

if (minimumCapacity - value.length > 0)

expandCapacity(minimumCapacity);

}

// 扩容方法

void expandCapacity(int minimumCapacity){

// 新容量 = 原长度 * 2 + 2

int newCapacity = value.length * 2 + 2;

// 看新字符串长度是否比默认扩容值还大

if (newCapacity - minimumCapacity < 0)

// 新容量=新字符串长度

newCapacity = minimumCapacity;

// 判断扩容值是否越界

if (newCapacity < 0) {

// 判断新字符串长度是否越界

if (minimumCapacity < 0)

throw new OutOfMemoryError();

newCapacity = Integer.MAX_VALUE;

}

value = Arrays.copyOf(value, newCapacity);

}

// 将原字符串拷贝到新容量的char数组

public static char[] copyOf(char[] original, int newLength) {

char[] copy = new char[newLength];

System.arraycopy(original, 0, copy, 0,

Math.min(original.length, newLength));

return copy;

}

// params: 0, 追加字符串长度,扩容后的数组,原字符串长度

public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin){

if (srcBegin < 0) {

throw new StringIndexOutOfBoundsException(srcBegin);

}

// 追加字符串长度 > 扩容后数组长度

if (srcEnd > value.length) {

throw new StringIndexOutOfBoundsException(srcEnd);

}

// 0 > 追加字符串长度

if (srcBegin > srcEnd) {

throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);

}

// 将指定数组拷贝到新数组

System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);

}

复制代码delete方法

public AbstractStringBuilder delete(int start, int end){

if (start < 0)

throw new StringIndexOutOfBoundsException(start);

if (end > count)

end = count;

if (start > end)

throw new StringIndexOutOfBoundsException();

int len = end - start;

if (len > 0) {

System.arraycopy(value, start+len, value, start, count-end);

count -= len;

}

return this;

}

// 删除制定坐标和之前的数据()

public AbstractStringBuilder deleteCharAt(int index){

if ((index < 0) || (index >= count))

throw new StringIndexOutOfBoundsException(index);

System.arraycopy(value, index+1, value, index, count-index-1);

count--;

return this;

}

复制代码

你瞅啥?这还需要啥解释吗?不就是调用 System.arraycopy()嘛

replace方法,都是熟悉的方法就不做赘述了。

public AbstractStringBuilder replace(int start, int end, String str){

if (start < 0)

throw new StringIndexOutOfBoundsException(start);

if (start > count)

throw new StringIndexOutOfBoundsException("start > length()");

if (start > end)

throw new StringIndexOutOfBoundsException("start > end");

if (end > count)

end = count;

int len = str.length();

int newCount = count + len - (end - start);

ensureCapacityInternal(newCount);

System.arraycopy(value, end, value, start + len, count - end);

str.getChars(value, start);

count = newCount;

return this;

}

复制代码

StringBuilder底层就是维护一个char[ ],调用System.arraycopy() 方法构建一个新的char[ ]

Fighting~ 最近在看Spring讲解,对Spring框架有了更深的了解,推荐大家看一看。想要成为架构师怎么能停留在会用的角度去看待技术呢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值