StringBuffer源码浅析(replace与substring方法)

一、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");
// 以上都是一些Bounds Checking,没什么好说。
if (end > count) //若替换字符边界超出字符长度,把字符长度赋予边界量
end = count;
int len = str.length();
//新字符长度,要加上替换长度,减去截取长度
int newCount = count + len - (end - start);
if (newCount > value.length) //是否大于已有容量,是则扩容
expandCapacity(newCount);
//复制数组,先预留替换字符串str的长度,看后面的解释。
//src the source array.
//srcPos starting position in the source array.
//dest the destination array.
//destPos starting position in the destination data.
//length the number of array elements to be copied.

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

str.getChars(value, start);//填充str到value,start索引开始

count = newCount;
return this;
}


len
|------|str str替换字符串


start end
|-------------+-----------+--------------| count
</count-end/>


start start + len
|-------------|------|--------------| count
预留 </count-end/>

从src的end开始复制,到dst的start+len开始
先预留用于存放str的空间,也就是从start开始 + len
而原先截取剩下的(长度为count-end),放到start+len的后面

二、substring方法,简单喔!
1、在StringBuffer类中源码

// 不解释
public synchronized String substring(int start) {
return substring(start, count);
}

public synchronized String substring(int start, int end) {
return super.substring(start, end); // super调用父类方法,真正源码在AbstractStringBuilder
}


2、进入AbstractStringBuilder抽象类围观

public String substring(int start, int end) {
//边界检查很重要骚年(疑问:为什么不把他们封装起来命名为boundsCheck()方法,看到其他地方都重复代码了)
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (end > count)
throw new StringIndexOutOfBoundsException(end);
if (start > end)
throw new StringIndexOutOfBoundsException(end - start);
// 没有很复杂,new一个String而已。
return new String(value, start, end - start);
}

3、进来看这个String的构造方法

/* @param value
* Array that is the source of characters
*
* @param offset
* The initial offset
*
* @param count
* The length
*/
public String(char value[], int offset, int count) {
if (offset < 0) {
throw new StringIndexOutOfBoundsException(offset);
}
if (count < 0) {
throw new StringIndexOutOfBoundsException(count);
}
// 这个重点条件 offset or count might be near -1>>>1.
if (offset > value.length - count) {
throw new StringIndexOutOfBoundsException(offset + count);
}
this.offset = 0;
this.count = count;
//这里又是利用copyOfRange(其实它也是利用System.arraycopy)
this.value = Arrays.copyOfRange(value, offset, offset+count);
}

不怕烦,把Arrays.copyOfRange源码再贴出来吧

public static char[] copyOfRange(char[] original, int from, int to) {
int newLength = to - from;
if (newLength < 0)
throw new IllegalArgumentException(from + " > " + to);
char[] copy = new char[newLength];
// 整天都是arraycopy,src数组到分配了newLength长度的新数组,并返回新数组。
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}

算蛮简单的,但都是我借你的方法用一下,你借我方法用一下,一个字,绕!
在想有些简单的,需不需要写博客记录?!
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值