字符串是不可变的 - 这意味着我永远不应该使用 += 而只能使用 StringBuffer?

发布于 2024-08-08 17:19:04 字数 141 浏览 13 评论 0原文

字符串是不可变的,这意味着一旦创建它们就无法更改。

那么,这是否意味着如果用 += 附加内容会比创建 StringBuffer 并向其附加文本占用更多内存?

如果你使用+=,你每次都会创建一个新的“对象”,并且必须保存在内存中,不是吗?

Strings are immutable, meaning, once they have been created they cannot be changed.

So, does this mean that it would take more memory if you append things with += than if you created a StringBuffer and appended text to that?

If you use +=, you would create a new 'object' each time that has to be saved in the memory, wouldn't you?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

意中人 2024-08-15 17:19:04

是的,每次使用 += 都会创建一个新对象。然而,这并不意味着这样做总是错误的。这取决于您是否希望将该值作为字符串,或者您是否只是打算使用它来进一步构建字符串。

如果您确实想要x + y的结果作为字符串,那么您不妨只使用字符串连接。但是,如果您真的要(比如说)循环并附加另一个字符串,等等 - 只需要在最后将结果作为字符串,那么 StringBuffer/StringBuilder 就是正确的选择。事实上,循环确实是 StringBuilder 比字符串连接更有价值的地方 - 5 次甚至 10 次直接连接的性能差异将非常小,但对于数千次,情况会变得更糟 - 基本上是因为你得到 O(N2 )连接的复杂性与 StringBuilder 的 O(N) 复杂性。

在 Java 5 及更高版本中,您基本上应该使用 StringBuilder - 它是不同步的,但这几乎总是可以的;想要在线程之间共享一个线程的情况非常罕见。

我有一篇关于所有这些内容的文章,您可能会觉得有用。

Yes, you will create a new object each time with +=. That doesn't mean it's always the wrong thing to do, however. It depends whether you want that value as a string, or whether you're just going to use it to build the string up further.

If you actually want the result of x + y as a string, then you might as well just use string concatenation. However, if you're really going to (say) loop round and append another string, and another, etc - only needing the result as a string at the very end, then StringBuffer/StringBuilder are the way to go. Indeed, looping is really where StringBuilder pays off over string concatenation - the performance difference for 5 or even 10 direct concatenations is going to be quite small, but for thousands it becomes a lot worse - basically because you get O(N2) complexity with concatenation vs O(N) complexity with StringBuilder.

In Java 5 and above, you should basically use StringBuilder - it's unsynchronized, but that's almost always okay; it's very rare to want to share one between threads.

I have an article on all of this which you might find useful.

拧巴小姐 2024-08-15 17:19:04

经验法则很简单:

如果您在循环中运行串联,请不要使用 +=

如果您在循环中运行串联,请使用 + = 根本不重要。 (除非性能关键的应用程序

Rule of thumb is simple:

If you are running concatenations in a loop, don't use +=

If you are not running concatenations in a loop, using += simply does not matter. (Unless a performance critical application

月亮坠入山谷 2024-08-15 17:19:04

在 Java 5 或更高版本中,StringBuffer 是线程安全的,因此会产生一些开销,除非您需要,否则您不应该为此付费。 StringBuilder 具有相同的 API,但不是线程安全的(即您应该只在单个线程内部使用它)。

是的,如果您要构建大型字符串,那么使用 StringBuilder 会更有效。将 StringBuilder 或 StringBuffer 作为 API 的一部分传递可能不值得。这太混乱了。

In Java 5 or later, StringBuffer is thread safe, and so has some overhead that you shouldn't pay for unless you need it. StringBuilder has the same API but is not thread safe (i.e. you should only use it internal to a single thread).

Yes, if you are building up large strings, it is more efficient to use StringBuilder. It is probably not worth it to pass StringBuilder or StringBuffer around as part of your API. This is too confusing.

伴我老 2024-08-15 17:19:04

我同意上面发布的所有答案,但它会帮助您更多地了解 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"。你明白我要说什么了吗?

如果你要做很多字符串连接,使用 StringBuffer 会提高你的性能,但如果你只做几个简单的字符串连接,Java 编译器可能会为你优化它,你不会注意到有什么区别表现

I agree with all the answers posted above, but it will help you a little bit to understand more about the way Java is implemented. The JVM uses StringBuffers internally to compile the String + operator (From the StringBuffer Javadoc):

String buffers are used by the
compiler to implement the binary
string concatenation operator +. For
example, the code:

     x = "a" + 4 + "c"

is compiled to the equivalent of:

     x = new StringBuffer().append("a").append(4).append("c")
                           .toString()

Likewise, x += "some new string" is equivalent to x = x + "some new string". Do you see where I'm going with this?

If you are doing a lot of String concatenations, using StringBuffer will increase your performance, but if you're only doing a couple of simple String concatenations, the Java compiler will probably optimize it for you, and you won't notice a difference in performance

怪我鬧 2024-08-15 17:19:04

是的。字符串是不可变的。对于偶尔使用,+= 就可以了。如果 += 操作密集,则应该转向 StringBuilder。

Yes. String is immutable. For occasional use, += is OK. If the += operation is intensive, you should turn to StringBuilder.

厌倦 2024-08-15 17:19:04

但是,一旦没有对旧字符串的引用,垃圾收集器最终将释放旧字符串

But the garbage collector will end up freeing the old strings once there are no references to them

暖阳 2024-08-15 17:19:04

确切地。如果线程安全不是问题,您应该使用 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 来尽可能优化字符串连接(如果现在还没有,也许将来可能会),我不会感到惊讶。

Exactly. You should use a StringBuilder though if thread-safety isn't an issue.

As a side note: There might be several String objects using the same backing char[] - for instance whenever you use substring(), no new char[] will be created which makes using it quite efficient.

Additionally, compilers may do some optimization for you. For instance if you do

static final String FOO = "foo";
static final String BAR = "bar"; 

String getFoobar() {
  return FOO + BAR; // no string concatenation at runtime
}

I wouldn't be surprised if the compiler would use StringBuilder internally to optimize String concatenation where possible - if not already maybe in the future.

莫言歌 2024-08-15 17:19:04

我认为它依赖于GC来收集带有废弃字符串的内存。
因此,如果您对字符串操作有很多操作,那么使用字符串生成器执行 += 肯定会更快。但对于大多数情况来说这应该不成问题。

I think it relies on the GC to collect the memory with the abandoned string.
So doing += with string builder will be definitely faster if you have a lot of operation on string manipulation. But it's shouldn't a problem for most cases.

屋顶上的小猫咪 2024-08-15 17:19:04

是的,您会的,这正是您应该使用 StringBuffer 来连接大量字符串的原因。

另请注意,从 Java 5 开始,您在大多数情况下也应该更喜欢 StringBuilder。它只是某种不同步的 StringBuffer。

Yes you would and that is exactly why you should use StringBuffer to concatenate alot of Strings.

Also note that since Java 5 you should also prefer StringBuilder most of the time. It's just some sort of unsynchronized StringBuffer.

隐诗 2024-08-15 17:19:04

你是对的,字符串是不可变的,所以如果你想在进行大量字符串连接时节省内存,你应该使用 StringBuilder 而不是 +=。

不过,你可能不介意。程序是为人类读者编写的,因此您可以清晰地进行操作。如果优化很重要,您应该首先进行分析。除非您的程序非常注重字符串活动,否则可能会存在其他瓶颈。

You're right that Strings are immutable, so if you're trying to conserve memory while doing a lot of string concatenation, you should use StringBuilder rather than +=.

However, you may not mind. Programs are written for their human readers, so you can go with clarity. If it's important that you optimize, you should profile first. Unless your program is very heavily weighted toward string activity, there will probably be other bottlenecks.

说不完的你爱 2024-08-15 17:19:04

它不会使用更多内存。是的,新的对象被创建,但旧的对象被回收。最终使用的内存量是相同的。

No

It will not use more memory. Yes, new objects are created, but the old ones are recycled. In the end, the amount of memory used is the same.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文