今天的内容是关于String,StringBuffer,StringBuilder的一些知识。
基本概念
String前文有详细的讲解,这里简要的说一下,String是被final关键字修饰的类,是一个字符串常量。StringBuffer是一个字符串变量(线程安全),StringBuilder也是一个字符串变量(非线程安全)。
String类型和StringBuffer类型的主要区别,其实是在于String是不可变的对象,因此在每次对String类型进行改变的时候,其实都等于生成了一个新的String对象,然后将指针指向新的String对象,所以经常改变内容的字符串最好不要用String。因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后,JVM的GC就会开始工作。
如果是使用StringBuffer类结果就不同了,每次结果都会对StringBuffer对象本身进行操作,而不是生成新的对象,再改变对象引用。所以一般情况下推荐使用StringBuffer,特别是字符串对象经常改变的情况下。而在某些特别的情况下,String对象的字符串拼接其实是被JVM解释成了StringBuffer对象的拼接,多以这时候String对象的速度并不会比StringBuffer对象慢,例如,下面的字符串对象生成中,String效率是远比StringBuffer快的。
String s1 = "abc" + "def";
StringBuffer sb = new StringBuffer("abc").append("def");
下面一段是性能的测试
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: StringTest
* @Description: TODO
* @Author: kevin
* @Date: 2019-03-26 20:28
* @Version: 1.0
**/
public class StringTest {
public static String BASEINFO = "Mr.H";
public static final int count = 2000000;
public static void doStringTest() {
String str = new String(BASEINFO);
long startTimes = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
str = str + "miss";
}
long endTimes = System.currentTimeMillis();
System.out.println("String总耗时:" + (endTimes - startTimes));
}
public static void doStringBufferTest() {
StringBuffer stringBuffer = new StringBuffer(BASEINFO);
long startTimes = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
stringBuffer = stringBuffer.append("miss");
}
long endTimes = System.currentTimeMillis();
System.out.println("StringBuffer总耗时:" + (endTimes - startTimes));
}
public static void doStringBuilderTest() {
StringBuilder stringBuilder = new StringBuilder(BASEINFO);
long startTimes = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
stringBuilder = stringBuilder.append("miss");
}
long endTimes = System.currentTimeMillis();
System.out.println("StringBuilder总耗时:" + (endTimes - startTimes));
}
public static void doStringBuilderListTest(List<String> mlist) {
StringBuilder sb = new StringBuilder();
long startTimes = System.currentTimeMillis();
for (String str: mlist) {
sb.append(str);
}
long endTimes = System.currentTimeMillis();
System.out.println(sb.toString() + "StringBuilder总耗时:" + (endTimes - startTimes));
}
public static void doStringBufferListTest(List<String> mlist) {
StringBuffer stringBuffer = new StringBuffer();
long startTimes = System.currentTimeMillis();
for (String str: mlist) {
stringBuffer.append(str);
}
long endTimes = System.currentTimeMillis();
System.out.println(stringBuffer.toString() + "StringBuffer总耗时:" + (endTimes - startTimes));
}
public static void main(String[] args) {
doStringTest();
doStringBufferTest();
doStringBuilderTest();
List<String> list = new ArrayList<>();
list.add(" I ");
list.add(" am ");
list.add(" the ");
list.add(" best ");
doStringBufferListTest(list);
doStringBuilderListTest(list);
}
}
===============
结果
===============
String总耗时:1413676
StringBuffer总耗时:35
StringBuilder总耗时:24
I am the best StringBuilder总耗时:0
I am the best StringBuffer总耗时:0
可以看到在拼接字符串的时候,String性能的消耗是惊人的。
参考链接
Java基础之String、StringBuffer与StringBuilder
String,StringBuffer与StringBuilder的区别?
StringBuffer和StringBuilder的区别
JAVA 中的 StringBuilder 和 StringBuffer 适用的场景是什么?
网友评论