黑马程序员技术交流社区
标题:
StringBuffer的问题
[打印本页]
作者:
火之意志
时间:
2013-5-22 23:15
标题:
StringBuffer的问题
本帖最后由 火之意志 于 2013-5-23 13:21 编辑
StringBuffer buffer=new StringBuffer();
buffer.append("HelloWorld!");
buffer.insert(5,buffer);
System.out.println(buffer);
结果为什么会是:HelloHelloHelloHe World!而不是HelloHello World World! ?
ps:通过试验,只要不是buffer对象,其他类型的对象都可以用insert方法插入
作者:
刘学明
时间:
2013-5-23 00:48
这个不知道 盲点 看别人回答
作者:
刘治广
时间:
2013-5-23 09:03
因为当你在(5,buffer)这个位置插入的时候 buffer是改变的,所有会不断的在第五个位置插入
作者:
史政法
时间:
2013-5-23 09:26
楼上说的貌似靠谱,,,,但是具体的插入过程呢?????
作者:
hdsjsql
时间:
2013-5-23 09:54
同求具体过程
作者:
刘治广
时间:
2013-5-23 09:55
因为buffer是同一个区域。一旦,这个区域添加了一个元素,那么,整个区域就是变化的。
结果就不可预料
作者:
张世威
时间:
2013-5-23 10:24
1、通过断点调试,发现buffer.insert(5,buffer) 这个方法的插入逻辑如下图
1.JPG
(70.23 KB, 下载次数: 0)
下载附件
2013-5-23 10:14 上传
2,关键点在于buffer1.insert(5,buffer2)是
取一个字符再插入一个字符
,当buffer1和buffer2不一样,这个自然不会有问题。
当buffer1==buffer2,后面取的字符可能是前面刚插入进去的,而不是原始需要插入的字符。
它只记字符索引值,这样就会出错。
3、看来源码里面还是有bug的。。。应该先把buffer2的字符放到temp里面,谁能想到,经过这么长的迭代,
会有value==s?关键位置源码
for (int i=start; i<end; i++)
value[dstOffset++] = s.charAt(i);
//AbstractStringBuilder的1115-1116行。
作者:
student
时间:
2013-5-23 10:41
这里,源和目的都是StringBuffer的实例对象buffer,在插入元素的过程中,buffer在不断变化,也就是说源和目的在不断地变化,变化的过程如下。
调用insert之前,buffer的值为“HelloWorld!”,insert调用过程就是将源转换成字符数组,然后将字符数组中的每一个元素插入到目的中,步骤如下:
注意,数据源和数据目的都在变化
1. 将数据源HelloWorld!的第
1
个
位置元素
H
,
插入到buffer的第
5
个位置
(下标从0开始,下
面相同
)
,buffer的值变成Hello
H
World!;
2. 将数据源Hello
H
World!的第
2
个
位置元素
e
,
插入到buffer的第
6
个位置,buffer的值变成Hello
He
World!;
3. 将数据源Hello
He
World!的第
3
个
位置元素
l
,
插入到buffer的第
7
个位置,buffer的值变成Hello
Hel
World!;
4. 将数据源
Hello
Hel
World!
的第
4
个
位置元素
l
,
插入到buffer的第
8
个位置,buffer的值变成Hello
Hell
World!;
5. 将数据源
Hello
Hell
World!
的第
5
个
位置元素
o
,
插入到buffer的第
9
个位置,buffer的值变成Hello
Hello
World!;
注意,下面开始有变化了,这种变化是因为数据源和数据目都是同一个
StringBuffer
对象的引用
buffer
造成的
6. 将数据源
Hello
Hell
o
World!
的第
6
个
位置元素
H
,
插入到buffer的第
10
个位置,buffer的值变成Hello
HelloH
World!;
7. 将数据源
Hello
Hell
oH
World!
的第
7
个
位置元素
e
,
插入到buffer的第
11
个位置,buffer的值变成Hello
HelloH
e
World!;
8. 将数据源
Hello
Hell
oHe
World!
的第
8
个
位置元素
l
,
插入到buffer的第
12
个位置,buffer的值变成Hello
HelloH
el
World!;
9. 将数据源
Hello
Hell
oHel
World!
的第
9
个
位置元素
l
,
插入到buffer的第
13
个位置,buffer的值变成Hello
HelloH
ell
World!;
10. 将数据源
Hello
Hell
oHell
World!
的第
10
个
位置元素
o
,
插入到buffer的第
14
个位置,buffer的值变成Hello
HelloH
ello
World!;
11. 将数据源
Hello
Hell
oHello
World!
的第
11
个
位置元素
H
,
插入到buffer的第
15
个位置,buffer的值变成Hello
HelloH
elloH
World!;
之所以执行11次将字符数组中的元素插入到buffer中,是因为原来的buffer的值“HelloWorld!”长度为11。
作者:
无妄无涯
时间:
2013-5-23 11:08
本帖最后由 无妄无涯 于 2013-5-23 12:09 编辑
由你的结果得出字符串应该是“Hello World”,即中间有空格。源字符串和目的字符串都是buffer,根据你的方式,buffer中的内容在不断变化。由于要加入的字符串“Hello World!”长12,因此在执行插入时会给buffer增加12字节的长度,然后从索引5处开始插入,直到24字节长度占满。过程是这样:
捕获.PNG
(4.1 KB, 下载次数: 0)
下载附件
2013-5-23 11:10 上传
如果想完成要求的效果可以这样:
class Test {
public static void main(String[] args) {
StringBuffer buffer=new StringBuffer();
StringBuffer buffer1=new StringBuffer();
buffer.append("HelloWorld!");
buffer1.append("Hello World!");
buffer.insert(5,buffer1);
System.out.println(buffer);
}
}
复制代码
作者:
Miss小强
时间:
2013-5-23 12:19
这个bug太吓人了。。。
为什么不这样做呢?
buffer.(5,buffer.toString);
作者:
Miss小强
时间:
2013-5-23 12:24
这个题目确实有意思:
但是如果说如果源代码中使用final关键字就不会出现这种问题了
从设计思想上说,即封装性;
你给我传递的参数是不允许改变的;
作者:
火之意志
时间:
2013-5-23 13:19
恩,大神们说的有道理,我自己也试验了,只要不是StringBuffer的对象,调用insert()方法都可以通过,唯独不能自己插入自己,既buffer。insert(3,buffer)是错误的,其他类型的对象都可以
作者:
张世威
时间:
2013-5-23 13:48
设置一断点,跟着程序走,就可以知道inser()方法里面是怎么插入的。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2