前言
很多初学者都不知道这三者之间的区别,我们今天一起来看一下。
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间
StringBuilder和StringBuffer是可变的,但StringBuilder多线程是不安全的,StringBuffer多线程是安全的。
String使用陷阱:
String s="a";//创建了一个字符串 s=s+"b"; //实际上原来的“a”字符串对象已经丢了,现在又产生了一个字符串s+"b"(也就是ab),如果多次执行这些,改变字符串的内容,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的数据放在循环中会大大降低效率,影响程序的性能。
初始化上的区别,String可以空赋值,后者不行,报错
①String
String s = null;
String s = “abc”;
②StringBuffer
StringBuffer s = null; //结果警告:Null pointer access: The variable result can only be null at this location
StringBuffer s = new StringBuffer();//StringBuffer对象是一个空的对象
StringBuffer s = new StringBuffer(“abc”);//创建带有内容的StringBuffer对象,对象的内容就是字符串”
String&StringBuider的效率问题
例:
String str="I"+"love"+"you"; //它应当先创建一个对象复制后合成"Ilove",然后再创建一个新的对象将两部分内容复制合成"Iloveyou",可见效率极低,但是由于string不可变,因此它本身不存在多线程的安全问题。 //实际上,java编辑器作者考虑到这个问题,在当你使用以上语句的时候,编辑器会自动引入java.lang.StringBuilder //StringBuilder对象能够被多次的修改,并且不产生新的未使用对象
因此:我们知道在一般情况下两者是没有区别的,但是如果创建的字符串对象是在for循环内做“+”,区别就会显现。
package springBuilder; import org.junit.jupiter.api.Test; public class SpringTest { @Test public void testString() { String str = ""; for (int i = 0; i < 3; i++) { str += i; } System.out.println(str); } @Test public void testStringBuilder() { StringBuilder builder = new StringBuilder(); for (int i = 0; i < 3; i++) { builder.append(i);//相当于builder=+i; } System.out.println(builder.toString()); } }
通过以上例子我们明显可以看到两者的效率高低:
String运行结果:
StringBuilder运行结果:
三者之间的关系
小结:
(1)如果要操作少量的数据用 String。
(2)多线程操作字符串缓冲区下操作大量数据 StringBuffer。
(3)单线程操作字符串缓冲区下操作大量数据 StringBuilder。