我正在尝试进行简单的字符串操作。输入是“谋杀”,我想得到“谋杀”。
我试过这个
String str = "murder";
StringBuffer buf = new StringBuffer(str);
// buf is now "murder", so i append the reverse which is "redrum"
buf.append(buf.reverse());
System.out.println(buf);
但现在我得到“redrumredrum”而不是“murderredrum”。
有人可以解释我的程序有什么问题吗?谢谢。
答案 0 :(得分:13)
该行:
buf.append(buf.reverse());
基本上执行以下操作:
buf.reverse(); // buf is now "redrum"
buf.append(buf);
这就是你得到"redrumredrum"
的原因。
也就是说,buf.reverse()
不会返回与StringBuffer
相反的新buf
。在它反转之后它返回buf
!
有很多方法可以“修复”这个问题,但最简单的方法是明确为逆转创建一个新的StringBuffer
,所以像这样:
buf.append(new StringBuffer(str).reverse());
String
和StringBuffer
String
是不可变的。另一方面,StringBuffer
是 mutable (这就是为什么你可以为append
提供的东西。
这就是String
的原因,转换方法确实会返回 new String
。这就是为什么这样的事情是“错误的”
String str = "murder";
str.toUpperCase(); // this is "wrong"!!!
System.out.println(str); // still "murder"
相反,你想做:
String str = "murder";
str = str.toUpperCase(); // YES!!!
System.out.println(str); // now "MURDER"!!!
但是,情况与StringBuffer
的情况大相径庭。大多数StringBuffer
方法返回StringBuffer
,但它们返回与上调用的实例相同的实例!他们 NOT 返回一个新的StringBuffer
实例。实际上,你可以自由地丢弃“结果”,因为这些方法已经完成了它们通过各种突变(即副作用)对它所调用的实例所做的事情。
这些方法可能已被声明为void
,但他们之所以基本上return this;
是因为它促进method chaining,允许你写类似的东西:
sb.append(thisThing).append(thatThing).append(oneMoreForGoodMeasure);
StringBuffer
vs StringBuilder
而不是StringBuffer
,您通常应该更喜欢StringBuilder
,这更快,因为它不是synchronized
。上述大多数讨论也适用于StringBuilder
。
来自文档:
StringBuffer
:线程安全,可变字符序列。 [...]从JDK 5开始,这个类已经补充了一个等效类,设计用于单个线程StringBuilder
,这通常应该是首选,因为它支持所有相同的操作但更快,如它没有执行同步。
StringBuilder
:一个可变的字符序列。 [...]StringBuilder
的实例不适合多线程使用。如果需要此类同步,则建议使用StringBuffer
。
这是对问题的另一种“修复”,可能更具可读性:
StringBuilder word = new StringBuilder("murder");
StringBuilder worddrow = new StringBuilder(); // starts empty
worddrow.append(word).append(word.reverse());
System.out.println(worddrow); // "murderredrum"
请注意,虽然这对短字符串应该没问题,但它确实使用了额外的缓冲区,这意味着它不是解决问题的最有效方法。
CharSequence
,是的,这可以做到!StringBuilder sb = new StringBuilder("ha");
sb.append(sb.append(sb));
System.out.println(sb); // "hahahaha"
答案 1 :(得分:1)
首先调用buf.reverse(),将stringbuffer修改为redrum。现在你将redrum附加到redrum