Strings are immutable - that means I should never use += and only StringBuffer?

天涯浪子 提交于 2019-12-30 06:01:47

问题


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?


回答1:


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.




回答2:


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




回答3:


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.




回答4:


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




回答5:


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




回答6:


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




回答7:


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.




回答8:


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.




回答9:


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.




回答10:


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.




回答11:


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.



来源:https://stackoverflow.com/questions/1635659/strings-are-immutable-that-means-i-should-never-use-and-only-stringbuffer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!