字符串类型详解
1.String 和 StringBuilder 和 StringBuffer 的互相转化
StringBuffer 类和StringBuilder 类都有toString()方法,可以返回字符序列的字符串表达形式。这两个类在初始化的时候,可以通过字符串作为参数,指定初始化的字符序列内容。
创建String,StringBuffer类,和StringBuilder类,将三者互相转化
public class StringInterchange {
public static void main(String[] args) {
String str = "String";
// String转换成StringBuffer
StringBuffer sbf = new StringBuffer(str);
// String转换成StringBuilder
StringBuilder sbd = new StringBuilder(str);
// StringBuffer转换成String
str = sbf.toString();
// StringBuilder转换成String
str = sbd.toString();
// StringBuffer转换成StringBuilder
StringBuilder bufferToBuilder = new StringBuilder(sbf.toString());
// StringBuilder转换成StringBuffer
StringBuffer builderToBuffer = new StringBuffer(sbd.toString());
}
}
2.String 和 StringBuilder 和 StringBuffer 的不同之处
String只能赋值一次,每一次内容发生改变都生成了一个新的对象,然后原有的对象引用新的对象,所以说String本身是不可改变的
。每一次改变String的字符串内容,都会在内存创建新的对象,而每一次生成新的对象都会对系统性能产生影响,这会降低Java虚拟机的工作效率。
而StringBuilder和StringBuffer不同,每次操作都是对自身对象的操作,不是生成新的对象,其所占的空间会随着字符内容增加而扩充,做大量的修改时,不会因为生成大量的匿名对象而影响系统性能。
哒~哒~
StringBuffer 和StringBuilder 也存在不同之处,StringBuffer
的方法使用“synchronized”关键字
进行修饰,这样保证了同时最多只有一个线程可以运行这些方法
,也就是保证了线程安全。StringBuilder则不具备这样的特点。
反过来说,也正是因为StringBuilder没有线程安全机制
,运行起来就不用考虑给线程加锁,所以运行效率比StringBuffer高
。
编写下面代码验证字符串操作和字符串生成器的操作的效率
public class Jerque {
public static void main(String[] args) {
String str = ""; // 创建空字符串
// 定义对字符串执行操作的起始时间
long starTime = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) { // 利用for循环执行10000次操作
str = str + i; // 循环追加字符串
}
long endTime = System.currentTimeMillis(); // 定义对字符串操作后的时间
long time = endTime - starTime; // 计算对字符串执行操作的时间
System.out.println("String循环1万次消耗时间:" + time); // 将执行的时间输出
StringBuilder builder = new StringBuilder(""); // 创建字符串生成器
starTime = System.currentTimeMillis(); // 定义操作执行前的时间
for (int j = 0; j < 10000; j++) { // 利用for循环进行操作
builder.append(j); // 循环追加字符
}
endTime = System.currentTimeMillis(); // 定义操作后的时间
time = endTime - starTime; // 追加操作执行的时间
System.out.println("StringBuilder循环1万次消耗时间:" + time); // 将操作时间输出
StringBuilder builder2 = new StringBuilder(""); // 创建字符串生成器
starTime = System.currentTimeMillis(); // 定义操作执行前的时间
for (int j = 0; j < 50000; j++) { // 利用for循环进行操作
builder2.append(j); // 循环追加字符
}
endTime = System.currentTimeMillis(); // 定义操作后的时间
time = endTime - starTime; // 追加操作执行的时间
System.out.println("StringBuilder循环5万次消耗时间:" + time); // 将操作时间输出
}
}
运行结果如下:
小结
类名 | String | StringBuilder | StringBuffer |
---|---|---|---|
对象类型 | 字符串常量 | 字符串变量 | 字符串变量 |
线程安全性 | 不安全 | 不安全 | 安全 |
执行效率(大多数情况) | 低 | 高 | 中 |
根据表中情况,可知各自的使用场景:
- 操作少,数据少,用String;
- 单线程,操作多,数据多,用StringBuilder;
- 多线程,操作多,数据多,用StringBuffer;
在做简单的字符串修改时,系统的完成时间很快,看不出区别。只有在大量修改时才能看出后两者的优势。所以,在操作简单扼字符串时,可以根据习惯随意使用
(相信大多数人应该像我一样习惯了用String)。