关于字符串反转的问题
我正在尝试进行简单的字符串操作。输入是“murder”,我想得到“murderredrum”。
我尝试过这个
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”。
有人可以解释我的程序出了什么问题吗?谢谢。
i am trying to do a simple string manipulation. input is "murder", i want to get "murderredrum".
i tried this
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);
but now i get "redrumredrum" instead of "murderredrum".
can someone explain what's wrong with my program? thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简短的回答
该行:
本质上执行以下操作:
这就是您得到“redrumredrum”的原因。
也就是说,buf.reverse() 不会返回与 buf 相反的新 StringBuffer。它在反转后返回
buf
!有很多方法可以“修复”此问题,但最简单的方法是显式创建一个新的
StringBuffer
来进行反转,因此如下所示:更深入的见解:比较
String
和 Java 中的StringBuffer
String
是不可变的。另一方面,StringBuffer
是可变的(这就是为什么您可以向其中追加
内容等)。这就是为什么使用
String
时,转换方法实际上返回一个newString
。这就是为什么这样的事情是“错误的”,而您却想要这样做:
但是,情况与
StringBuffer
相差甚远。大多数StringBuffer
方法确实返回StringBuffer
,但它们返回与调用它的实例相同!它们不返回一个新的StringBuffer
实例。事实上,您可以随意丢弃“结果”,因为这些方法已经通过对其调用的实例进行各种突变(即副作用)来完成它们所做的事情。这些方法可以被声明为
void
,但它们本质上返回this;
的原因是因为它有助于方法链接,允许您编写类似以下内容:相关问题
附录:
StringBuffer
与StringBuilder
而不是
StringBuffer
,您通常应该更喜欢StringBuilder
,它更快,因为它不是同步
。上面的大部分讨论也适用于StringBuilder
。从文档中:
相关问题
额外材料!替代解决方案!
这是问题的替代“修复”,可能更具可读性:
请注意,虽然这对于短字符串应该很好,但它确实使用了额外的缓冲区,这意味着它不是解决问题的最有效方法。
相关问题
CharSequence
,是的,这是可以做到的!又是福利材料!笑到最后!
The short answer
The line:
essentially does the following:
This is why you get
"redrumredrum"
.That is,
buf.reverse()
doesn't return a newStringBuffer
which is the reverse ofbuf
. It returnsbuf
, after it had reversed itself!There are many ways to "fix" this, but the easiest would be to explicitly create a new
StringBuffer
for the reversal, so something like this:Deeper insight: comparing
String
andStringBuffer
String
in Java is immutable. On the other hand,StringBuffer
is mutable (which is why you can, among other things,append
things to it).This is why with
String
, a transforming method really returns a newString
. This is why something like this is "wrong"Instead you want to do:
However, the situation is far from analogous with
StringBuffer
. MostStringBuffer
methods do returnStringBuffer
, but they return the same instance that it was invoked on! They do NOT return a newStringBuffer
instance. In fact, you're free to discard the "result", because these methods have already accomplished what they do through various mutations (i.e. side effects) to the instance it's invoked upon.These methods could've been declared as
void
, but the reason why they essentiallyreturn this;
instead is because it facilitates method chaining, allowing you to write something like:Related questions
Appendix:
StringBuffer
vsStringBuilder
Instead of
StringBuffer
, you should generally preferStringBuilder
, which is faster because it's notsynchronized
. Most of the discussions above also applies toStringBuilder
.From the documentation:
Related questions
Bonus material! Alternative solution!
Here's an alternative "fix" to the problem that is perhaps more readable:
Note that while this should do fine for short strings, it does use an extra buffer which means that it's not the most efficient way to solve the problem.
Related questions
CharSequence
, yes this can be done!Bonus material again! The last laugh!
buf.reverse() 首先被调用,它将字符串缓冲区修改为 redrum。现在您正在将 redrum 附加到 redrum
buf.reverse() gets called first it modifies the stringbuffer to redrum. Now you are appending redrum to redrum