Java 如何重新分配 StringBuffer 的值?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2591867/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Reassign value of StringBuffer?
提问by Biju CD
How can we re assign the value of a StringBuffer or StringBuilder Variable?
我们如何重新分配 StringBuffer 或 StringBuilder 变量的值?
StringBuffer sb=new StringBuffer("teststr");
Now i have to change the value of sb to "testString" without emptying the contents. I am looking at a method which can do this assignment directly without using separate memory allocation.I think we can do it only after emptying the contents.
现在我必须在不清空内容的情况下将 sb 的值更改为“testString”。我正在寻找一种方法,它可以在不使用单独的内存分配的情况下直接进行此分配。我认为我们只能在清空内容后才能进行。
采纳答案by polygenelubricants
It should first be mentioned that StringBuilder
is generally preferred to StringBuffer
. From StringBuffer
's own API:
首先应该提到的StringBuilder
是,通常首选StringBuffer
. 从StringBuffer
自己的 API:
As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread,
StringBuilder
. TheStringBuilder
class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.
从 JDK 5 版本开始,这个类已经补充了一个设计用于单线程的等效类,
StringBuilder
. 所述StringBuilder
类通常应优先使用这一个,因为它支持所有相同的操作,但它是快的,因为它不执行同步。
That said, I will stick to StringBuffer
for the rest of the answer because that's what you're asking; everything that StringBuffer
does, StringBuilder
also... except synchronization, which is generally unneeded. So unless you're using the buffer in multiple threads, switching to StringBuilder
is a simple task.
也就是说,我将坚持StringBuffer
回答其余的问题,因为这就是您要问的问题;所做的一切StringBuffer
,StringBuilder
也......除了同步,这通常是不需要的。因此,除非您在多个线程中使用缓冲区,否则切换到StringBuilder
是一项简单的任务。
The question
问题
StringBuffer sb = new StringBuffer("teststr");
"Now i have to change the value of
sb
to"testString"
without emptying the contents"
“现在我要改变的值
sb
,以"testString"
不排空内容”
So you want sb
to have the String
value "testString"
in its buffer? There are many ways to do this, and I will list some of them to illustrate how to use the API.
所以你想在它的缓冲区中sb
有String
值"testString"
吗?有很多方法可以做到这一点,我将列出其中一些方法来说明如何使用 API。
The optimal solution: it performs the minimum edit from "teststr"
to "testString"
. It's impossible to do it any faster than this.
最佳解决方案:它执行从"teststr"
到的最小编辑"testString"
。不可能比这更快。
StringBuffer sb = new StringBuffer("teststr");
sb.setCharAt(4, 'S');
sb.append("ing");
assert sb.toString().equals("testString");
This needlessly overwrites "tr"
with "tr"
.
这不必要地"tr"
用"tr"
.
StringBuffer sb = new StringBuffer("teststr");
sb.replace(4, sb.length(), "String");
assert sb.toString().equals("testString");
This involves shifts due to deleteCharAt
and insert
.
这涉及由于deleteCharAt
和引起的变化insert
。
StringBuffer sb = new StringBuffer("teststr");
sb.deleteCharAt(4);
sb.insert(4, 'S');
sb.append("ing");
assert sb.toString().equals("testString");
This is a bit different now: it doesn't magically know that it has "teststr"
that it needs to edit to "testString"
; it assumes only that the StringBuffer
contains at least one occurrence of "str"
somewhere, and that it needs to be replaced by "String"
.
现在有点不同:它并不神奇地知道"teststr"
它需要编辑为"testString"
;它只假设StringBuffer
包含至少一次出现在"str"
某处,并且需要替换为"String"
。
StringBuffer sb = new StringBuffer("strtest");
int idx = sb.indexOf("str");
sb.replace(idx, idx + 3, "String");
assert sb.toString().equals("Stringtest");
Let's say now that you want to replace ALLoccurrences of "str"
and replace it with "String"
. A StringBuffer
doesn't have this functionality built-in. You can try to do it yourself in the most efficient way possible, either in-place (probably with a 2-pass algorithm) or using a second StringBuffer
, etc.
现在假设您要替换所有出现的"str"
并将其替换为"String"
. AStringBuffer
没有内置此功能。您可以尝试以最有效的方式自己完成,或者就地(可能使用 2-pass 算法)或使用 secondStringBuffer
等。
But instead I will use the replace(CharSequence, CharSequence)
from String
. This will be more than good enough in most cases, and is definitely a lot more clear and easier to maintain. It's linear in the length of the input string, so it's asymptotically optimal.
但相反,我将使用replace(CharSequence, CharSequence)
from String
。在大多数情况下,这已经足够了,而且绝对更清晰,更易于维护。它在输入字符串的长度上是线性的,所以它是渐近最优的。
String before = "str1str2str3";
String after = before.replace("str", "String");
assert after.equals("String1String2String3");
Discussions
讨论
"I am looking for the method to assign value later by using previous memory location"
“我正在寻找稍后通过使用以前的内存位置分配值的方法”
The exact memory location shouldn't really be a concern for you; in fact, both StringBuilder
and StringBuffer
will reallocate its internal buffer to different memory locations whenever necessary. The only way to prevent that would be to ensureCapacity
(or set it through the constructor) so that its internal buffer will always be big enough and it would never need to be reallocated.
确切的内存位置不应该是您真正关心的问题;实际上,无论是StringBuilder
和StringBuffer
将重新分配其内部缓冲区到不同的存储位置在必要时。防止这种情况的唯一方法是ensureCapacity
(或通过构造函数设置它)使其内部缓冲区始终足够大并且永远不需要重新分配。
However, even if StringBuffer
does reallocate its internal buffer once in a while, it should not be a problem in most cases. Most data structures that dynamically grows (ArrayList
, HashMap
, etc) do them in a way that preserves algorithmically optimal operations, taking advantage of cost amortization. I will not go through amortized analysis here, but unless you're doing real-time systems etc, this shouldn't be a problem for most applications.
但是,即使偶尔StringBuffer
重新分配其内部缓冲区,在大多数情况下也不应该成为问题。大多数动态增长的数据结构(ArrayList
,HashMap
等)以保留算法优化操作的方式进行,利用成本摊销。我不会在这里进行摊销分析,但除非你在做实时系统等,否则这对于大多数应用程序来说应该不是问题。
Obviously I'm not aware of the specifics of your need, but there is a fear of premature optimization since you seem to be worrying about things that most people have the luxury of never having to worry about.
显然,我不知道您需要的具体细节,但是担心过早优化,因为您似乎担心大多数人有幸永远不必担心的事情。
回答by Michael Borgwardt
What do you mean with "reassign"? You can empty the contents by using setLength()
and then start appending new content, if that's what you mean.
“重新分配”是什么意思?您可以通过使用清空内容setLength()
,然后开始附加新内容,如果这就是您的意思。
Edit: For changing parts of the content, you can use replace()
.
编辑:要更改部分内容,您可以使用replace()
.
Generally, this kind of question can be easily answered by looking at the API doc of the classes in question.
通常,通过查看相关类的 API 文档可以轻松回答此类问题。
回答by Itay Maman
You can convert to/from a String, as follows:
您可以转换为/从字符串,如下所示:
StringBuffer buf = new StringBuffer();
buf.append("s1");
buf.append("s2");
StringBuilder sb = new StringBuilder(buf.toString());
// Now sb, contains "s1s2" and you can further append to it
回答by Michael Aaron Safyan
You can use a StringBuilder
in place of a StringBuffer
, which is typically what people do if they can (StringBuilder
isn't synchronized so it is faster but not threadsafe). If you need to initialize the contents of one with the other, use the toString()
method to get the string representation. To recycle an existing StringBuilder
or StringBuffer
, simply call setLength(0)
.
您可以使用 aStringBuilder
代替 a StringBuffer
,这通常是人们可以做的事情(StringBuilder
不同步,因此速度更快但不是线程安全的)。如果需要用另一个初始化其中一个的内容,请使用该toString()
方法获取字符串表示。要回收现有的StringBuilder
or StringBuffer
,只需调用setLength(0)
。
Edit
You can overwrite a range of elements with the replace()
function. To change the entire value to newval
, you would use buffer.replace(0,buffer.length(),newval)
. See also:
编辑
您可以使用该replace()
函数覆盖一系列元素。要将整个值更改为newval
,您可以使用buffer.replace(0,buffer.length(),newval)
. 也可以看看:
回答by Marcus Adams
You might be looking for the replace() method of the StringBuffer:
您可能正在寻找 StringBuffer 的 replace() 方法:
StringBuffer sb=new StringBuffer("teststr");
sb.replace(0, sb.length() - 1, "newstr");
Internally, it removes the original string, then inserts the new string, but it may save you a step from this:
在内部,它删除原始字符串,然后插入新字符串,但它可以为您节省一个步骤:
StringBuffer sb=new StringBuffer("teststr");
sb.delete(0, sb.length() - 1);
sb.append("newstr");
Using setLength(0) reassigns a zero length StringBuffer to the variable, which, I guess, is not what you want:
使用 setLength(0) 将零长度 StringBuffer 重新分配给变量,我猜这不是您想要的:
StringBuffer sb=new StringBuffer("teststr");
// Reassign sb to a new, empty StringBuffer
sb.setLength(0);
sb.append("newstr");
回答by webjockey
sb.setLength(0);
sb.append("testString");
回答by Martijn Courteaux
Indeed, I think replace()
is the best way. I checked the Java-Source code. It really overwrites the old characters.
确实,我认为replace()
是最好的方法。我检查了 Java 源代码。它确实覆盖了旧字符。
Here is the source code from replace():
这是replace()的源代码:
public AbstractStringBuffer replace(int start, int end, String str)
{
if (start < 0 || start > count || start > end)
throw new StringIndexOutOfBoundsException(start);
int len = str.count;
// Calculate the difference in 'count' after the replace.
int delta = len - (end > count ? count : end) + start;
ensureCapacity_unsynchronized(count + delta);
if (delta != 0 && end < count)
VMSystem.arraycopy(value, end, value, end + delta, count - end);
str.getChars(0, len, value, start);
count += delta;
return this;
}
回答by SM ANSARI
Changing entire value of StringBuffer:
更改 StringBuffer 的整个值:
StringBuffer sb = new StringBuffer("word");
sb.setLength(0); // setting its length to 0 for making the object empty
sb.append("text");
This is how you can change the entire value of StringBuffer.
这就是您可以更改 StringBuffer 的整个值的方法。