您的位置:首页 > 产品设计 > UI/UE

Java中StringBuffer和StringBuilder类总结

2014-09-06 13:44 337 查看
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间,StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象,StringBuffer和StringBuilder类功能基本相似。

当对字符串进行修改的时候,需要使用StringBuffer和StringBuilder类。和String类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象。

StringBuilder类在Java 5中被提出,它和StringBuffer之间的最大不同在于StringBuilder的方法不是线程安全的(不能同步访问)。由于StringBuilder相较于StringBuffer有速度优势,所以多数情况下建议使用StringBuilder类。然而在应用程序要求线程安全的情况下,则必须使用StringBuffer类。

public class Test{

public static void main(String args[]){
StringBuffer sBuffer = new StringBuffer(" test");
sBuffer.append(" String Buffer");
System.ou.println(sBuffer);
}
}


结果为:test String Buffer

1. String 类

  String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。

String a = "a"; //假设a指向地址0x0001

a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。

因此String的操作都是改变赋值地址而不是改变值操作。

2. StringBuffer

StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。

StringBuffer buf=new StringBuffer(); //分配长16字节的字符缓冲区

StringBuffer buf=new StringBuffer(512); //分配长512字节的字符缓冲区

StringBuffer buf=new StringBuffer("this is a test")//在缓冲区中存放了字符串,并在后面预留了16字节的空缓冲区。

3.StringBuilder

  StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。

4.线程安全

StringBuffer 线程安全

StringBuilder 线程不安全

5.速度

一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。

6.总结

(1).如果要操作少量的数据用 = String

(2).单线程操作字符串缓冲区 下操作大量数据 = StringBuilder

(3).多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

package StringDemo;

public class Test {
final static int time = 50000; // 循环次数
public Test() {
}

public void test(String s) {
long begin = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
s += "add";
}
long over = System.currentTimeMillis();
System.out.println("操作" + s.getClass().getName() + "类型使用的时间为:"
+ (over - begin) + "毫秒");
}

public void test(StringBuffer s) {
long begin = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
s.append("add");
}
long over = System.currentTimeMillis();
System.out.println("操作" + s.getClass().getCanonicalName() + "类型使用的时间为:"
+ (over - begin) + "毫秒");
}

public void test(StringBuilder s) {
long begin = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
s.append("add");
}
long over = System.currentTimeMillis();
System.out.println("操作" + s.getClass().getName() + "类型使用的时间为:"
+ (over - begin) + "毫秒");
}

/* 对 String 直接进行字符串拼接的测试 */
public void test2() {
String s2 = "abcd";
long begin = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
String s = s2 + s2 + s2;
}
long over = System.currentTimeMillis();
System.out.println("操作字符串对象引用相加类型使用的时间为:" + (over - begin) + "毫秒");
}

public void test3() {
long begin = System.currentTimeMillis();
for (int i = 0; i < time; i++) {
String s = "abcd" + "abcd" + "abcd";
}
long over = System.currentTimeMillis();
System.out.println("操作字符串相加使用的时间为:" + (over - begin) + "毫秒");
}

public static void main(String[] args) {
String s1 = "abcd";
StringBuffer st1 = new StringBuffer("abcd");
StringBuilder st2 = new StringBuilder("abcd");
Test tc = new Test();
tc.test(s1);
tc.test(st1);
tc.test(st2);
tc.test2();
tc.test3();
}
}


以下是StringBuffer类支持的主要方法:

序号方法描述
1public StringBuffer append(String s)

将指定的字符串追加到此字符序列。
2public StringBuffer reverse()

将此字符序列用其反转形式取代。
3public delete(int start, int end)

移除此序列的子字符串中的字符。
4public insert(int offset, int i)

int
参数的字符串表示形式插入此序列中。
5replace(int start, int end, String str)

使用给定
String
中的字符替换此序列的子字符串中的字符。
其他的方法可以查询手册。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: