指定初始化容量,根据容量对数组进行初始化。
获取字符串长度。
AbstractStringBuilder.java中的相关代码:
@Override
public int length() {
return count;
}
获取容量,即最多可以保存的字符数量。
AbstractStringBuilder.java中的相关代码:
public int capacity() {
// 返回数组长度
return value.length;
}
对数组的容量进行检测,并在容量小于要求时进行扩容。
AbstractStringBuilder.java中的相关代码:
public void ensureCapacity(int minimumCapacity) {
// 若要求的容量大于0
if (minimumCapacity > 0)
// 则调用ensureCapacityInternal方法
ensureCapacityInternal(minimumCapacity);
}
1)ensureCapacityInternal方法
AbstractStringBuilder.java中的相关代码:
private void ensureCapacityInternal(int minimumCapacity) {
// 若要求的容量大于当前数组的长度,即需要扩容
if (minimumCapacity - value.length > 0) {
// 调用newCapacity方法,获取扩容后的容量
// 将当前字符数组的内容复制到扩容后的新数组中,并返回新数组
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
2)newCapacity方法
AbstractStringBuilder.java中的相关代码:
private int newCapacity(int minCapacity) {
// 计算新的容量为当前容量乘的2倍再加2
int newCapacity = (value.length << 1) + 2;
// 如果新计算的容量还是小于要求的容量
if (newCapacity - minCapacity < 0) {
// 设置新容量为要求的容量
newCapacity = minCapacity;
}
// 如果新容量小于等于0或者新容量超过最大容量
// 则返回调用hugeCapacity方法的结果,该方法用于获得一个相对较大的容量
// 否则,返回新计算的容量
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
3)hugeCapacity方法
AbstractStringBuilder.java中的相关代码:
private int hugeCapacity(int minCapacity) {
// 若要求的容量大于整型数据的最大值,则抛出异常
if (Integer.MAX_VALUE - minCapacity < 0) {
throw new OutOfMemoryError();
}
// 若要求的容量大于最大容量,则返回要求的容量,否则返回最大容量
// 即返回两者中较大的一个
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
该方法用于释放字符数组中没有用到空间。
AbstractStringBuilder.java中的相关代码:
public void trimToSize() {
// 若已经使用的容量小于总容量
if (count < value.length) {
// 根据已经使用的容量,创建新的数组,将原数组的内容复制到新数组中
// 保存新数组
value = Arrays.copyOf(value, count);
}
}
该方法用于设置字符串的长度。
AbstractStringBuilder.java中的相关代码:
public void setLength(int newLength) {
// 若设置的长度小于0,则抛出异常
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
// 进行扩容
ensureCapacityInternal(newLength);
// 如果已经使用的空间小于总空间
if (count < newLength) {
// 用’\0’对没有用到空间进行填充
Arrays.fill(value, count, newLength, '\0');
}
// 设置已经使用使用的空间的数量
count = newLength;
}
获取字符串中指定位置的字符。
AbstractStringBuilder.java中的相关代码:
@Override
public char charAt(int index) {
// 若指定的位置小于0,或超过字符串的长度,则抛出异常
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
// 返回数组中对应位置的字符
return value[index];
}
将字符串中从srcBegin开始到srcEnd结束的字符填充到dst数组从dstBegin开始的位置。
AbstractStringBuilder.java中的相关代码:
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin){
// 若字符串起始位置小于0
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
// 若字符串终止位置小于0,或字符串终止位置超出了字符串的长度
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
// 若字符串的起始位置超过了字符串的终止位置
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
// 复制字符串的内容到数组中。
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
将字符串中指定位置index处的字符设置为指定字符ch。
AbstractStringBuilder.java中的相关代码:
public void setCharAt(int index, char ch) {
// 若起始位置小于0,或超过字符串最大长度
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
// 设置字符数组index处字符为ch
value[index] = ch;
}
向字符串末尾附加一个字符串形式的对象。
1)参数为String
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder append(String str) {
// 若附加的字符串为空
if (str == null)
// 则调用appendNull方法,附加”null”,并返回
return appendNull();
// 若附加的字符串不为空
// 获取附加的字符串的长度
int len = str.length();
// 进行扩容,新字符串长度为原长度count+附加长度len
ensureCapacityInternal(count + len);
// 调用附加字符串的getChars方法,从源字符串末尾count位置开始添加
str.getChars(0, len, value, count);
// 设置新字符串的长度
count += len;
// 返回
return this;
}
参数为StringBuffer和AbstractStringBuilder时的处理过程也是如此。
a)appendNull方法
AbstractStringBuilder.java中的相关代码:
private AbstractStringBuilder appendNull() {
int c = count;
// 扩容
ensureCapacityInternal(c + 4);
// 拼接”null”
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
// 设置新字符串的长度
count = c;
// 返回
return this;
}
2)参数为Object
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder append(Object obj) {
// 调用Object对象的toString方法,拼接
return append(String.valueOf(obj));
}
3)参数为char[]
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder append(char[] str) {
// 获取附加的字符串的长度
int len = str.length;
// 扩容
ensureCapacityInternal(count + len);
// 将str中长度为len的内容从起始位置0复制到value数组count后
System.arraycopy(str, 0, value, count, len);
// 设置新字符串的长度
count += len;
// 返回
return this;
}
4)参数为boolean
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder append(boolean b) {
// 为true
if (b) {
// 容量加4
ensureCapacityInternal(count + 4);
// 拼接”true”
value[count++] = 't';
value[count++] = 'r';
value[count++] = 'u';
value[count++] = 'e';
} else {// 为false
// 容量加5
ensureCapacityInternal(count + 5);
// 拼接”fasle”
value[count++] = 'f';
value[count++] = 'a';
value[count++] = 'l';
value[count++] = 's';
value[count++] = 'e';
}
// 返回
return this;
}
5)参数为char
AbstractStringBuilder.java中的相关代码:
@Override
public AbstractStringBuilder append(char c) {
// 容量加1
ensureCapacityInternal(count + 1);
// 拼接字符
value[count++] = c;
// 返回
return this;
}
6)参数为int
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder append(int i) {
// 若为整型的最小值,即-2147483648
if (i == Integer.MIN_VALUE) {
// 直接拼接
append("-2147483648");
// 返回
return this;
}
// 通过调用Integer的静态方法stringSize,获取i的长度
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
// 计算拼接后的长度
int spaceNeeded = count + appendedLength;
// 扩容
ensureCapacityInternal(spaceNeeded);
// 调用Integer的getChars方法进行拼接
Integer.getChars(i, spaceNeeded, value);
// 设置新字符串长度
count = spaceNeeded;
返回
return this;
}
参数为long时,处理过程和int相似,只不过在拼接字符串时调用的是Long的静态方法getChars。
7)参数为float
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder append(float f) {
// 调用FloatingDecimal的静态方法appendTo方法进行拼接
FloatingDecimal.appendTo(f,this);
// 返回
return this;
}
参数double与float处理过程完全相同。
删除字符串中指定开始位置和终止位置之间的字符。
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder delete(int start, int end) {
// 若起始位置小于0
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
// 若终止位置超过字符串长度
if (end > count)
// 设置终止位置为字符串末尾
end = count;
// 若起始位置大于终止位置
if (start > end)
throw new StringIndexOutOfBoundsException();
// 计算需要删除字符串的长度
int len = end - start;
// 若需要删除字符串的长度大于0
if (len > 0) {
// 将终止位置后面的字符串复制到起始位置后面
System.arraycopy(value, start+len, value, start, count-end);
// 设置删除后的字符串的长度
count -= len;
}
// 返回
return this;
}
删除字符串中指定位置的字符。
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder deleteCharAt(int index) {
// 若指定位置小于0,或超过字符串长度
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
// 将index后面的字符串复制到index处
System.arraycopy(value, index+1, value, index, count-index-1);
// 新字符串长度为源字符串长度减1
count--;
// 返回
return this;
}
将起始位置start和终止位置end之间的字符串替换为字符串str。
AbstractStringBuilder.java中的相关代码:
public AbstractStringBuilder replace(int start, int end, String str) {
// 若起始位置小于0
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);
// 从替换后被覆盖的位置开始将后面的字符复制到
// 加入替换进来的字符串后的末尾
### 最后
毕竟工作也这么久了 ,除了途虎一轮,也七七八八面试了不少大厂,像阿里、饿了么、美团、滴滴这些面试过程就不一一写在这篇文章上了。我会整理一份详细的面试过程及大家想知道的一些问题细节
### 美团面试经验
![美团面试](https://img-blog.csdnimg.cn/img_convert/df1e667721f4d713e3f01b18a70758f2.webp?x-oss-process=image/format,png)
字节面试经验
![字节面试](https://img-blog.csdnimg.cn/img_convert/2bd7b07220faf4d7727cbab36fe3ab6b.webp?x-oss-process=image/format,png)
菜鸟面试经验
![菜鸟面试](https://img-blog.csdnimg.cn/img_convert/2eca1071424bf878a2f7d043f88241de.webp?x-oss-process=image/format,png)
蚂蚁金服面试经验
![蚂蚁金服](https://img-blog.csdnimg.cn/img_convert/18355751801d58eaf2e54f56ca62b4f0.webp?x-oss-process=image/format,png)
唯品会面试经验
![唯品会](https://img-blog.csdnimg.cn/img_convert/6f15b98b280b9c90b3788906bccf1374.webp?x-oss-process=image/format,png)
>因篇幅有限,图文无法详细发出
xception("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);
// 从替换后被覆盖的位置开始将后面的字符复制到
// 加入替换进来的字符串后的末尾
### 最后
毕竟工作也这么久了 ,除了途虎一轮,也七七八八面试了不少大厂,像阿里、饿了么、美团、滴滴这些面试过程就不一一写在这篇文章上了。我会整理一份详细的面试过程及大家想知道的一些问题细节
### 美团面试经验
[外链图片转存中...(img-UXshgLGd-1714497724852)]
字节面试经验
[外链图片转存中...(img-FpMdKtTR-1714497724853)]
菜鸟面试经验
[外链图片转存中...(img-1DLZCorr-1714497724853)]
蚂蚁金服面试经验
[外链图片转存中...(img-fp9mHkUt-1714497724853)]
唯品会面试经验
[外链图片转存中...(img-7swGW2f0-1714497724853)]
>因篇幅有限,图文无法详细发出
> **本文已被[CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】](https://bbs.csdn.net/topics/618154847)收录**