首页 > 代码库 > String、StringBuffer、StringBuilder三者的区别
String、StringBuffer、StringBuilder三者的区别
String、StringBuffer、StringBuilder这三个都可以用在字符串处理上面,但它们三究竟有什么区别呢?
先来看看String,String是final类,是不可变的对象,在进行字符串连接的时候是新建一个字符串,进行连接后,最后赋值,如果对String赋值N次,就会在内存中为新的对象分配N个新的空间,在内存中保存N个这个对象的副本,浪费系统资源。
比如:String s1 = new String(“行者”);s1 = s1 + “摩罗”;实际上String s1 = new String(“行者”);是在全局共享的字符串常量池里驻留了”行者”这个实例,然后通过new String(String)创建了一个内容与”行者”一样的实例,然后将new出来的这个实例的引用赋值给变量s1,当对s1执行加操作的时候,实际上是生成了一个新的实例:”行者摩罗”,然后将”行者摩罗”这个实例的引用又赋值给了s1,原来”行者”那个实例只要GC没有回收,它仍然存在于常量池中,并且内容还是”行者”,内容和地址都没有发生改变。
接着再看看StringBuffer,StringBuffer是线程安全的,同步的,可变的,不会生成新的对象,不会像String那样对”副本”进行操作,而是直接进行拼接,常用的方法有append()和insert()。
最后来看StringBuilder,StringBuilder是JDK1.5以后的版本才有的,1.5以前的只有String和StringBuffer。StringBuilder和StringBuffer功能一样,实际上StringBuilder提供一个与StringBuffer兼容的API,只是StringBuilder不保证同步,所以它不是线程安全的。
简单的说 StringBuilder 事先先分配内存, 如果 StringBuilder没有先定义长度,则默认分配的长度为16;当 StringBuilder字符长度小于等于16时,则StringBuilder不重新分配内存。当 StringBuilder 字符长度大于16 小于 32的时候,StringBuilder又重新分配16的2倍 ,依次类推。所以StringBuilder的内存空间不够也是要扩容的,如果分配的空间远远大于需要量,也会很浪费 资源。所以,初始化StringBuilder的时候最好根据需要设置容量,避免浪费 。
另外通过StringBuilder.Capacity可以获取StringBuilder的真实的分配的内存大小,通过StringBuilder.Length可以获取 StringBuilder字符串的长度。
最后再来看几个例子:
eg1.
String s = "aa" + "bb";eg2.
StringBuilder strBuilder = new StringBuilder(); strBuilder.append("aa"); strBuilder.append("bb");eg1中在内存中实际上有三个实例:"aa","bb"以及"aabb",而eg2中就不同了,他虽然也有三个实例,但分别是:"aa","bb","aabb\0..."因为strBuilder.capacity()没有指定长度,所以默认长度是16,所以"aabb"后面用12个空格填充满,而不是eg1中的直接是"aabb"。
再来看案例2:
eg3.
String s = ""; for (int i=0; i<10; i++) { s = s + String.valueOf(i); }eg4.
StringBuilder strBuilder = new StringBuilder(100); for (int i=0; i<10; i++) { strBuilder = strBuilder.append(String.valueOf(i)); }这里eg3生成了"0","1","2","3","4","5","6","7","8","9"以及"01","012",..."0123456789"
eg4则生成了"0","1","2","3","4","5","6","7","8","9"和"0123456789",并没有生成"01","012,","0123"这些中间产物。
总结:
1.String不可变,StringBuffer和StringBuilder可变
2.String和StringBUffer是线程安全的,StringBuilder线程不安全,因为它不同步
3.如果字符串经常变,使用StringBuilder最好,因为它不会产生”副本“,而且效率比StringBuffer高,但如果需要线程安全,就必须使用StringBuffer
尊重版权,转载请注明本文链接
欢迎关注行者摩罗微信公众号(xingzhemoluo),共同交流编程经验,扫描下方二维码即可;
String、StringBuffer、StringBuilder三者的区别