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中在内存中实际上有1个实例:"aabb",因为对于字符串的"+"操作,只要没有引用存在,就会被编译器自动优化成一个字符串,即该方法跟String s = "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),共同交流编程经验,扫描下方二维码即可;



      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值