如何重新分配 StringBuffer 的值?

2022-09-03 03:22:46

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

StringBuffer sb=new StringBuffer("teststr");

现在我必须将sb的值更改为“testString”,而无需清空内容。我正在研究一种可以在不使用单独内存分配的情况下直接完成此分配的方法。我认为我们只有在清空内容后才能做到这一点。


答案 1
sb.setLength(0);
sb.append("testString");

答案 2

首先应该提到的是,通常比 .来自 StringBuffer 自己的 APIStringBuilderStringBuffer

从版本 JDK 5 开始,此类已使用一个等效类进行补充,该类设计为供单个线程使用。该类通常应优先于此类使用,因为它支持所有相同的操作,但它更快,因为它不执行同步。StringBuilderStringBuilder

也就是说,我将坚持其余的答案,因为这就是你要问的;所有能做的事情,也...除了同步,这通常是不需要的。因此,除非在多个线程中使用缓冲区,否则切换到 是一项简单的任务。StringBufferStringBufferStringBuilderStringBuilder


问题

StringBuffer sb = new StringBuffer("teststr");

“现在我必须在不清空内容的情况下将的值更改为”sb"testString"

所以你想让值在其缓冲区中吗?有很多方法可以做到这一点,我将列出其中一些来说明如何使用API。sbString"testString"


最佳解决方案:它执行从 到 的最小编辑。不可能比这更快。"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");

假设现在您要替换 所有出现的 ,并将其替换为 .A 没有内置此功能。您可以尝试以最有效的方式自己完成,无论是就地(可能使用2-pass算法)还是使用第二个,等等。"str""String"StringBufferStringBuffer

但相反,我将使用 from .在大多数情况下,这已经足够好了,并且肯定更清晰,更易于维护。它在输入字符串的长度上是线性的,因此它是渐近最优的。replace(CharSequence, CharSequence)String

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

讨论

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

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

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

显然,我不知道你的需求的具体情况,但是你担心过早优化,因为你似乎担心大多数人永远不必担心的事情。