字符串是不可变的,这意味着,一旦创建它们就无法更改。
那么,这是否意味着如果你用+ =附加东西比你创建一个StringBuffer并附加文本那么需要更多的内存?
如果使用+ =,每次必须保存在内存中时都会创建一个新的“对象”,不是吗?
答案 0 :(得分:25)
是的,每次用+ =创建一个新对象。然而,这并不意味着它总是错误的做法。这取决于您是否希望将该值作为字符串,或者您是否只是使用它来进一步构建字符串。
如果您实际上希望 x + y
的结果作为字符串,那么您也可以使用字符串连接。但是,如果你真的要(比方说)循环并附加另一个字符串,另一个字符串等 - 只需要将结果作为字符串放在最后,那么StringBuffer / StringBuilder就是你要走的路。实际上,循环实际上是StringBuilder在字符串连接上得到回报的结果 - 5个甚至10个直接连接的性能差异将非常小,但是对于数千个,它变得更糟糕 - 主要是因为你得到了O(N 2 )串联与StringBuilder的O(N)复杂性的复杂性。
在Java 5及以上版本中,你基本上应该使用StringBuilder - 它是不同步的,但这几乎总是好的;想要在线程之间共享一个是非常罕见的。
我有article on all of this你可能觉得有用。
答案 1 :(得分:7)
如果您在循环中运行连接,请不要使用+=
如果您不在循环中运行连接,则使用+=
无关紧要。 (除非是性能关键应用程序
答案 2 :(得分:5)
在Java 5或更高版本中,StringBuffer是线程安全的,因此除非您需要,否则您应该支付一些开销。 StringBuilder具有相同的API,但不是线程安全的(即,您只应在单个线程内部使用它。)
是的,如果要构建大字符串,使用StringBuilder会更有效。作为API的一部分传递StringBuilder或StringBuffer可能是不值得的。这太混乱了。
答案 3 :(得分:5)
我同意上面发布的所有答案,但它会帮助您更多地了解Java的实现方式。 JVM在内部使用StringBuffers来编译String +运算符(来自StringBuffer Javadoc):
字符串缓冲区由。使用 编译器实现二进制 字符串连接运算符+。对于 例如,代码:
x = "a" + 4 + "c"
编译为相当于:
x = new StringBuffer().append("a").append(4).append("c") .toString()
同样,x += "some new string"
相当于x = x + "some new string"
。你知道我要去哪儿吗?
如果你正在进行很多String连接,使用StringBuffer会提高你的性能,但是如果你只做几个简单的String连接,Java编译器可能会为你优化它,你不会注意到性能差异
答案 4 :(得分:3)
是。字符串是不可变的。偶尔使用,+ =即可。如果+ =操作密集,则应转向StringBuilder。
答案 5 :(得分:1)
完全。如果线程安全不是问题,您应该使用StringBuilder。
作为旁注:可能有几个String对象使用相同的后备char [] - 例如,每当使用substring()时,都不会创建新的char [],这使得使用它非常有效。
此外,编译器可能会为您做一些优化。例如,如果你这样做
static final String FOO = "foo";
static final String BAR = "bar";
String getFoobar() {
return FOO + BAR; // no string concatenation at runtime
}
如果编译器在内部使用StringBuilder来尽可能地优化字符串连接 - 如果不是将来可能的话,我不会感到惊讶。
答案 6 :(得分:1)
但是一旦没有对它们的引用,垃圾收集器将最终释放旧字符串
答案 7 :(得分:0)
我认为它依赖于GC用废弃的字符串来收集内存。 因此,如果对字符串操作进行大量操作,那么使用字符串构建器执行+ =肯定会更快。但对大多数情况来说,这不应该是一个问题。
答案 8 :(得分:0)
是的,你会这就是为什么你应该使用StringBuffer来连接很多字符串。
另请注意,从Java 5开始,您大多数时候也应该更喜欢StringBuilder。它只是某种不同步的StringBuffer。
答案 9 :(得分:0)
你是对的,Strings是不可变的,所以如果你在做大量的字符串连接时试图节省内存,你应该使用StringBuilder而不是+ =。
但是,你可能不介意。程序是为人类读者编写的,因此您可以清晰地进行。如果您进行优化非常重要,那么您应首先进行分析。除非你的程序非常重视字符串活动,否则可能会有其他瓶颈。
答案 10 :(得分:0)
它不会使用更多内存。是的,创建了新对象,但旧对象被回收。最后,使用的内存量是相同的。