题干:
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
分析:
这题属于简单题,思路有2.其一利用额外的空间,直接再创建一个StringBuffer,将这个Buffer中的内容向其中添加即可,遇到空格添加”%20“,反之添加其原本的内容。其二即为在原buffer上进行修改,直接在原位置上用replace替换为“%20”。
注意这里容易发生错误的是repalce方法,看下面两个例子:
我们想要将a替换为t
StringBuffer sb = new StringBuffer();
sb.append("dasd");
//sb.deleteCharAt(1);
sb.replace(1,2,"t");
System.out.println(sb.toString());
输出为dtsd,符合预期
另外一种写法:
StringBuffer sb = new StringBuffer();
sb.append("dasd");
//sb.deleteCharAt(1);
sb.replace(1,1"t");
System.out.println(sb.toString());
输出为dtasd,并未实现替换,而是在原位置上进行了添加,为什么呢?原因很简单,StringBuffer的replace方法源码如下:
@Override
public synchronized StringBuffer replace(int start, int end, String str) {
toStringCache = null;
super.replace(start, end, str);//继承其父类的replace方法
return this;
}
可见StringBuffer的replace方法是直接继承了其父类AbstractStringBuffer的replace方法,如下:
public AbstractStringBuilder replace(int start, int end, String str) {
//前面几个if都是为了增强方法的鲁棒性
if (start < 0)
throw new StringIndexOutOfBoundsException(start);
if (start > count)//count为StringBuffer中实际被使用的字符串个数
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);//此为核心步骤,利用System.arraycopy方法,将原数组的扩容len长度,扩容起始位置为start,从end及其之后的元素也要相应的向后移动len长度,明显从end开始的内容都未被删除,而是直接后移了len长度,只有start到end-1的位置被替换
str.getChars(value, start);//将目标字符串添加进刚刚扩容的空闲空间内,实现替换
count = newCount;
return this;
}
具体方法1的代码如下:
public String replaceSpace(StringBuffer str) {
StringBuffer sb = new StringBuffer();
for(int i=0;i<str.length();i++){
if(str.charAt(i)==' '){
sb.append("%20");
}
else {
sb.append(str.charAt(i));
}
}
return sb.toString();
}
方法2如下:
public String replaceSpace(StringBuffer str) {
StringBuffer sb = new StringBuffer();
for(int i=0;i<str.length();i++){
if(str.charAt(i)==' '){
sb.replace(i,i+1,"%20");
}
}
return sb.toString();
}
由此可见,这么简单的一道题目,如果深挖源码的话,还是有蛮多值得思考的东西的,与君共勉~