Java StringBuffer类与StringBuilder类
在我们平时日常操作中需要经常用到字符串类型的变量,在有一些时候我们需要将这些变量进行拼接以达到我们预期的效果,这个时候如果我们遇到一些大量拼接的字符串问题的时候还继续使用“String”的话就显得不够效率了,因为“String”每次拼接之后并不是真的就拼接一个,它是每次拼接后就相当于又重新创建一个”String”对象了,大量的拼接“String”就会不断的重复创建新的对象,这样的资源耗损是非常大,效率也很低。
所以当对字符串进行大量的拼接操作的时候,需要使用 StringBuffer 和 StringBuilder 类。
和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
StringBuilder类在java 5中被提出它和StringBuffer类之间最大的区别是StringBuilder类是线程不安全的(不能同步访问)。
但由于StringBuilder相对StringBuffer有存在速度优势多数情况下是建议使用StringBuilder类的除非特别需求线程安全的情况下使用StringBuffer类。
下面是一个例子:
StringBuffer类支持的主要方法
方法 | 说明 |
---|---|
public StringBuffer append(String s) | 将指定的字符串追加到此字符序列。 |
public StringBuffer reverse() | 将此字符序列用其反转形式取代。 |
public delete(int start, int end) | 移除此序列的子字符串中的字符。 |
public insert(int offset, int i) | 将int参数的字符串表示形式插入此序列中。 |
replace(int start, int end, String str) | 使用给定String中的字符替换此序列的子字符串中的字符。 |
这里补充一下
关于线程安全,即使你真的遇到了这样的场景,很不幸的是,恐怕你仍然有 99.99…99% 的情况下没有必要选择 stringbuffer,因为 stringbuffer 的线程安全,仅仅是保证 jvm 不抛出异常顺利的往下执行而已,
它可不保证逻辑正确和调用顺序正确。大多数时候,我们需要的不仅仅是线程安全,而是锁。
在 jdk1.5 的时候,提供一个非线程安全的 stringbuffer 实现,并命名为 stringbuilder。顺便,javac 好像大概也是从这个版本开始,把所有用加号连接的 string 运算都隐式的改写成 stringbuilder,也就是说,从 jdk1.5 开始,在单行用加号拼接字符串几乎没有任何性能损失了。
如果没有循环的情况下,单行用加号拼接字符串是没有性能损失的,java 编译器会隐式的替换成 stringbuilder,但在有循环的情况下,编译器没法做到足够智能的替换,仍然会有不必要的性能损耗,因此,用循环拼接字符串的时候,还是老老实实的用 stringbuilder 吧。