[JAVA/Android] String, StringBuilder, StringBuffer之间的关系
2012-09-24 15:55
489 查看
在项目中遇到了关于字符串操作的问题,简单比较了String , StringBuilder和StringBuffer之间区别和使用场景,这里做一个总结记录。
1. 这三个类的主要区别,可以从以下两个方面来描述:
Mutability 差别:
Thread-Safety Difference:
StringBuffer和String Builder之间最大的区别是:前者是线程安全的,也就是说,可以在多个线程中访问;而后者只能在一个线程中访问。Java较早版本只有StringBuffer,后来加入了String Builder,因为这样可以提高一些运行效率。
2 . 实际使用中,进行选择的原则:
如果只是需要一个固定不变的字符串,或者少量的字符串改变操作(尤其是纯字符串的拼接),就用String类即可
如果需要对一个字符串做大量的涉及内容改变的操作,而且这些操作在一个线程中完成,就用StringBuilder类
如果需要对一个字符串做大量的涉及内容改变的操作,而且这些操作可能在多个线程中完成,就用StringBuffer类
3. 效率和其他分析
从拼接等操作的效率上看,基本的关系是:StringBuilder > StringBuffer > String。可以参考一下两篇文章:
是 String , StringBuffer 还是 StringBuilder ? --- http://www.blogjava.net/chenpengyi/archive/2006/05/04/44492.html
StringBuilder vs StringBuffer
vs String.concat - done righ --- http://kaioa.com/node/59
还有一个深入分析的文章,摘录如下(http://stackoverflow.com/questions/2971315/string-stringbuffer-and-stringbuilder):
--------------------------------------------------------
摘录部分 -------------------------------------------------------------------------
The Basics:
an immutable class, it can't be changed.
a mutable class that can be appended to, characters replaced or removed and ultimately converted to a
the original synchronized version of
You should prefer
all cases where you have only a single thread accessing your object.
The Details:
Also note that
magic, they just use an Array as a backing object and that Array has to be re-allocated when ever it gets full. Be sure and create your
large enough originally where they don't have to be constantly re-sized every time
called.
The re-sizing can get very degenerate. It basically re-sizes the backing Array to 2 times its current size every time it needs to be expanded. This can result in large amounts of RAM getting allocated and not used when
start to grow large.
In Java
the scenes. So for simple cases there is no benefit of declaring your own. But if you are building
that are large, say less than 4k, then declaring
is only 16 characters. If your
going to be less than 10k then initialize it with the constructor to 10k to be safe. But if it is initialize to 10k then you write 1 character more than 10k, it will get re-allocated and copied to a 20k array. So initializing high is better than to low.
In the auto re-size case, at the 17th character the backing Array gets re-allocated and copied to 32 characters, at the 33th character this happens again and you get to re-allocated and copy the Array into 64 characters. You can see how this degenerates to lots of
re-allocations and copies which is what you really are trying to avoid using
the first place.
This is from the JDK 6 Source code for AbstractStringBuilder
A best practice is to initialize the
little bit larger than you think you are going to need if you don't know right off hand how big the
be but you can guess. One allocation of slightly more memory than you need is going to be better than lots of re-allocations and copies.
Also beware of initializing a
a
that will only allocated the size of the String + 16 characters, which in most cases will just start the degenerate re-allocation and copy cycle that you are trying to avoid. The following is straight from the Java 6 source code.
If you by chance do end up with an instance of
you didn't create and can't control the constructor that is called, there is a way to avoid the degenerate re-allocate and copy behavior. Call
the size you want to ensure your resulting
fit into.
The Alternatives:
Just as a note, if you are doing really heavy
and manipulation, there is a much more performance oriented alternative called Ropes .
Another alternative, is to create a
by sub-classing
and adding counters to track the number of characters on every
other mutation operations of the list, then override
create a
the exact size you need and loop through the list and build the output, you can even make that
instance variable and 'cache' the results of
only have to re-generate it when something changes.
Also don't forget about
building fixed formatted output, which can be optimized by the compiler as they make it better.
附录:
Java中StringBuilder的清空方法比较
http://blog.csdn.net/roserose0002/article/details/6972391
1. 这三个类的主要区别,可以从以下两个方面来描述:
Mutability 差别:
String是immutable的,如果改变了String的值,系统就会另外生成一个String对象。于此相反,
StringBuffer和
StringBuilder是 mutable的,可以直接修改他们的值(内容)而不会生成新的对象。
Thread-Safety Difference:
StringBuffer和String Builder之间最大的区别是:前者是线程安全的,也就是说,可以在多个线程中访问;而后者只能在一个线程中访问。Java较早版本只有StringBuffer,后来加入了String Builder,因为这样可以提高一些运行效率。
2 . 实际使用中,进行选择的原则:
如果只是需要一个固定不变的字符串,或者少量的字符串改变操作(尤其是纯字符串的拼接),就用String类即可
如果需要对一个字符串做大量的涉及内容改变的操作,而且这些操作在一个线程中完成,就用StringBuilder类
如果需要对一个字符串做大量的涉及内容改变的操作,而且这些操作可能在多个线程中完成,就用StringBuffer类
3. 效率和其他分析
从拼接等操作的效率上看,基本的关系是:StringBuilder > StringBuffer > String。可以参考一下两篇文章:
是 String , StringBuffer 还是 StringBuilder ? --- http://www.blogjava.net/chenpengyi/archive/2006/05/04/44492.html
StringBuilder vs StringBuffer
vs String.concat - done righ --- http://kaioa.com/node/59
还有一个深入分析的文章,摘录如下(http://stackoverflow.com/questions/2971315/string-stringbuffer-and-stringbuilder):
--------------------------------------------------------
摘录部分 -------------------------------------------------------------------------
The Basics:
Stringis
an immutable class, it can't be changed.
StringBuilderis
a mutable class that can be appended to, characters replaced or removed and ultimately converted to a
String
StringBufferis
the original synchronized version of
StringBuilder
You should prefer
StringBuilderin
all cases where you have only a single thread accessing your object.
The Details:
Also note that
StringBuilder/Buffersaren't
magic, they just use an Array as a backing object and that Array has to be re-allocated when ever it gets full. Be sure and create your
StringBuilder/Bufferobjects
large enough originally where they don't have to be constantly re-sized every time
.append()gets
called.
The re-sizing can get very degenerate. It basically re-sizes the backing Array to 2 times its current size every time it needs to be expanded. This can result in large amounts of RAM getting allocated and not used when
StringBuilder/Bufferclasses
start to grow large.
In Java
String x = "A" + "B";uses a
StringBuilderbehind
the scenes. So for simple cases there is no benefit of declaring your own. But if you are building
Stringobjects
that are large, say less than 4k, then declaring
StringBuilder sb = StringBuilder(4096);is much more efficient than concatenation or using the default which
is only 16 characters. If your
Stringis
going to be less than 10k then initialize it with the constructor to 10k to be safe. But if it is initialize to 10k then you write 1 character more than 10k, it will get re-allocated and copied to a 20k array. So initializing high is better than to low.
In the auto re-size case, at the 17th character the backing Array gets re-allocated and copied to 32 characters, at the 33th character this happens again and you get to re-allocated and copy the Array into 64 characters. You can see how this degenerates to lots of
re-allocations and copies which is what you really are trying to avoid using
StringBuilder/Bufferin
the first place.
This is from the JDK 6 Source code for AbstractStringBuilder
void expandCapacity(int minimumCapacity) { int newCapacity = (value.length + 1) * 2; if (newCapacity < 0) { newCapacity = Integer.MAX_VALUE; } else if (minimumCapacity > newCapacity) { newCapacity = minimumCapacity; } value = Arrays.copyOf(value, newCapacity); }
A best practice is to initialize the
StringBuilder/Buffera
little bit larger than you think you are going to need if you don't know right off hand how big the
Stringwill
be but you can guess. One allocation of slightly more memory than you need is going to be better than lots of re-allocations and copies.
Also beware of initializing a
StringBuilder/Bufferwith
a
Stringas
that will only allocated the size of the String + 16 characters, which in most cases will just start the degenerate re-allocation and copy cycle that you are trying to avoid. The following is straight from the Java 6 source code.
public StringBuilder(String str) { super(str.length() + 16); append(str); }
If you by chance do end up with an instance of
StringBuilder/Bufferthat
you didn't create and can't control the constructor that is called, there is a way to avoid the degenerate re-allocate and copy behavior. Call
.ensureCapacity()with
the size you want to ensure your resulting
Stringwill
fit into.
The Alternatives:
Just as a note, if you are doing really heavy
Stringbuilding
and manipulation, there is a much more performance oriented alternative called Ropes .
Another alternative, is to create a
StringListimplemenation
by sub-classing
ArrayList<String>,
and adding counters to track the number of characters on every
.append()and
other mutation operations of the list, then override
.toString()to
create a
StringBuilderof
the exact size you need and loop through the list and build the output, you can even make that
StringBuilderan
instance variable and 'cache' the results of
.toString()and
only have to re-generate it when something changes.
Also don't forget about
String.format()when
building fixed formatted output, which can be optimized by the compiler as they make it better.
附录:
Java中StringBuilder的清空方法比较
http://blog.csdn.net/roserose0002/article/details/6972391
相关文章推荐
- 回首Java——String、StringBuffer与StringBuilder之间区别
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系 详细出处参考:http://www.jb51.net/article/33398.htm
- String、StringBuffer与StringBuilder之间区别-----(java复习)
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- java中StringBuilder、StringBuffer、String类之间的关系
- 【Java基础】String,StringBuffer,StringBuilder之间的区别
- Java学习札记14:一个比较String、StringBuffer和StringBuilder之间效率差别的简单例子
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- java中StringBuilder、StringBuffer、String类之间的关系
- JAVA之String,StringBuffer与StringBuilder三者之间的区别
- Java中的String,StringBuilder,StringBuffer三者的方法及关系
- String、StringBuffer、StringBuilder之间关系及其使用
- 【java】String、StringBuilder和StringBuffer之间的区别
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- Java中String,StringBuffer,StringBuilder之间区别
- java学习---String、StringBuffer与StringBuilder之间区别
- Java之String与CharSequence、StringBuffer与StringBuilder之间区别
- String, StringBuilder, StringBuffer 之间的区别 - Java