如何重新分配StringBuffer的值?

时间:2010-04-07 11:10:58

标签: java string stringbuilder stringbuffer

我们如何重新赋值StringBuffer或StringBuilder变量的值?

StringBuffer sb=new StringBuffer("teststr");

现在我必须将sb的值更改为“testString”而不清空内容。 我正在研究一种方法,它可以直接执行此分配而无需使用单独的内存分配。我认为只有在清空内容后才能执行此操作。

8 个答案:

答案 0 :(得分:21)

sb.setLength(0);
sb.append("testString");

答案 1 :(得分:16)

首先应该提到StringBuilder通常优先于StringBuffer。来自StringBuffer's own API

  

自JDK 5发布以来,该类已经补充了一个等效类,专为单个线程StringBuilder使用而设计。通常应优先使用StringBuilder类,因为它支持所有相同的操作,但它更快,因为它不执行同步。

那就是说,我将坚持StringBuffer以获得答案的其余部分,因为这就是你所要求的; StringBuffer所做的一切,StringBuilder也......除了同步,这通常是不需要的。因此,除非您在多个线程中使用缓冲区,否则切换到StringBuilder是一项简单的任务。


问题

StringBuffer sb = new StringBuffer("teststr");
  

“现在我必须将sb的值更改为"testString",而不会清空内容”

您希望sb在其缓冲区中包含String"testString"吗?有很多方法可以做到这一点,我将列出其中一些来说明如何使用API​​。


最佳解决方案:它执行从"teststr""testString"的最小编辑。这不可能比这更快。

StringBuffer sb = new StringBuffer("teststr");
sb.setCharAt(4, 'S');
sb.append("ing");
assert sb.toString().equals("testString");

这会不必要地用"tr"覆盖"tr"

StringBuffer sb = new StringBuffer("teststr");
sb.replace(4, sb.length(), "String");
assert sb.toString().equals("testString");

这涉及由deleteCharAtinsert引起的转变。

StringBuffer sb = new StringBuffer("teststr");
sb.deleteCharAt(4);
sb.insert(4, 'S');
sb.append("ing");
assert sb.toString().equals("testString");

现在有点不同了:它并没有神奇地知道它需要编辑"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");

现在假设您要替换{em>所有次"str"次出现并将其替换为"String"StringBuffer没有内置此功能。您可以尝试以最有效的方式自行完成,就地(可能使用2遍算法)或使用第二个StringBuffer等。

但我将使用replace(CharSequence, CharSequence)中的String。在大多数情况下,这将是非常好的,并且肯定更清晰,更容易维护。它在输入字符串的长度上是线性的,因此它是渐近最优的。

String before = "str1str2str3";
String after = before.replace("str", "String");
assert after.equals("String1String2String3");

讨论

  

“我正在寻找以后通过使用先前的内存位置来分配值的方法”

确切的记忆位置不应该是你真正关心的问题;实际上,StringBuilderStringBuffer都会在必要时将其内部缓冲区重新分配到不同的内存位置。防止这种情况的唯一方法是ensureCapacity(或通过构造函数设置它),这样它的内部缓冲区总是足够大,而且永远不需要重新分配。

但是,即使StringBuffer偶尔重新分配其内部缓冲区,在大多数情况下也不应该成为问题。大多数动态增长的数据结构(ArrayListHashMap等)以保留算法优化操作的方式执行它们,利用成本摊销。我不会在这里进行摊销分析,但除非您正在进行实时系统等,否则这对大多数应用程序来说都不是问题。

显然我并不知道你需要的具体细节,但是因为你似乎担心大多数人都不必担心的事情,所以担心会过早优化。

答案 2 :(得分:8)

“重新分配”是什么意思?您可以使用setLength()清空内容,然后开始添加新内容,如果这就是您的意思。

修改:要更改部分内容,您可以使用replace()

通常,通过查看相关课程的API文档可以轻松回答这类问题。

答案 3 :(得分:3)

您可以使用StringBuilder代替StringBuffer,这通常是人们可以做的事情(StringBuilder未同步,因此它更快但不是线程安全的)。如果需要使用另一个来初始化one的内容,请使用toString()方法获取字符串表示。要回收现有的StringBuilderStringBuffer,只需致电setLength(0)

修改
您可以使用replace()函数覆盖一系列元素。要将整个值更改为newval,您可以使用buffer.replace(0,buffer.length(),newval)。另见:

答案 4 :(得分:2)

您可能正在寻找StringBuffer的替换()方法:

StringBuffer sb=new StringBuffer("teststr");
sb.replace(0, sb.length() - 1, "newstr");

在内部,它删除原始字符串,然后插入新字符串,但它可以为您节省一步:

StringBuffer sb=new StringBuffer("teststr");
sb.delete(0, sb.length() - 1);
sb.append("newstr");

使用setLength(0)将一个零长度的StringBuffer重新分配给变量,我想这不是你想要的:

StringBuffer sb=new StringBuffer("teststr");
// Reassign sb to a new, empty StringBuffer
sb.setLength(0);
sb.append("newstr");

答案 5 :(得分:1)

的确,我认为replace()是最好的方法。我检查了Java-Source代码。它真的会覆盖旧字符。

以下是来自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;
  }

答案 6 :(得分:0)

您可以转换为String,如下所示:

 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

答案 7 :(得分:-1)

更改StringBuffer的整个值:

  StringBuffer sb = new StringBuffer("word");
  sb.setLength(0); // setting its length to 0 for making the object empty
  sb.append("text");

这是你可以改变StringBuffer的整个值的方法。