String,StringBuffer,StringBuilder,StringJoiner有什么区别?项目中什么时候用?

String,StringBuffer,StringBuilder,StringJoiner有什么区别?项目中什么时候用?


先做一个简介:

  1. String : 是java.lang包中的immutable类,String里面所有的属性几乎也是final,由于它的不可变性,类似拼接,裁剪字符串等动作都会产生大量无用的中间对象。由于字符串操作在项目中很常见,所以对String的操作对项目的性能往往有很明显的影响。
  2. StringBuffer : 这个类是为了解决String拼接产生多余对象的问题而提供的一个类。StringBuffer保证了线程的安全,也带来了多余的开销。
  3. StringBuilder : StringBuilder的功能与StringBuffer一样。但是区别是StringBuilder没有处理线程安全,减少了开销。
  4. StringJoiner:StringJoiner也是用来拼接字符的。不过它是用来分割字符,拼接前缀和后缀的,拼接实现也是使用StringBuilder, 可以说它是StringBuilder的升级版,所以它也是线程不安全的。

区别总结:

1.StringBuffer算是String的敷生的一个类,而StringBuilder却又是Oracle公司为了减少线程开销,而诞生的一个类(这个区别有点扯…),StringJoiner是为了更加方便分割字符,精炼代码?

2.字符串的主要操作还是String。StringBuffer,StringJoiner与StringBuilder主要还是用来拼接字符串的。

3.StringBuffer与StringBuilder的长度是可以定义的,而String不能(因为String是个对象)。StringJoiner也不行,它的长度是主体字符串,字符串前缀,字符串后缀组成

4.这几种主要用的地方都不一样,下面会有介绍。

然后就是使用:

  1. String:它被用于裁剪,拼接。(当然如果拼接过多的话还是建议用StringBuffer,或者> StringBuild)搜索字符串,比较字符串,截取字符串,转换大小写等。在项目中不经常发生变化的业务场景中,优先使用String
  2. StringBuffer:用于拼接,替换,删除。在项目多线程环境下运行,如:XML解析,HTTP参数解析与封装等。
  3. StringBuilder:它同StringBuffer使用方式一样,不过在项目中使用的地方建议是单线程的环境下,如:SQL拼接,JSON封装等。
  4. StringJoiner:用来封装前缀后缀以及间隔符都是一样的字符串,将集合数据拼接为字符串等(StringBuilder也可以进行这样的操作,只是麻烦些)
    // StringJoiner使用方式
    public void stringJoinerTest() {
        StringJoiner sj = new StringJoiner(":", "[", "]");
        sj.add("George").add("Sally").add("Fred");
        String desiredString = sj.toString();
        // 输出字符串:[George:Sally:Fred]
        System.out.println(desiredString);

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4);
        String commaSeparatedNumbers = numbers.stream()
                .map(i -> i.toString())
                .collect(Collectors.joining(", "));
         // 输出字符串:1, 2, 3, 4
        System.out.println(commaSeparatedNumbers);
	}
	
	public void stringBuildTest() {
        StringBuilder stringBuilder = new StringBuilder();
        String stringBuilderToString = stringBuilder.append("[").append("George")
                .append(":").append("Sally")
                .append(":").append("Fred")
                .append("]").toString();
        // 输出字符串:[George:Sally:Fred]
        System.out.println(stringBuilderToString);

        StringBuilder stringBuilderNumbers = new StringBuilder();
        for (int i = 0; i < numbers.size(); i++) {
            stringBuilderNumbers.append(numbers.get(i));
            if (i != numbers.size() - 1) {
                stringBuilderNumbers.append(", ");
            }
        }
        // 输出字符串:1, 2, 3, 4
        System.out.println(stringBuilderNumbers.toString());
	}

拓展>>

1.String JDK9后大改:将数据存储方式从char[]数组修改为byte[]数组在加上一个标示编码,然后重写所有相关的类,以保证没有任何性能上的损失。


2.StringBuffer与StringBuilder两者都是由byte[]数组(在JDK 9 以后),所以能定义长度,但是如果不定义的话那默认为16。如果当前对象操作,使得数组长度超过了16,那么数组就会创建新的,还要进行arraycopy,丢弃原来数组。


3.讲String的时候必须得讲一下字符串的缓存。字符串的缓存核心方法就是intern();这个方法了。这个方法主要逻辑是判断当前字符串是否存在于StringTable,如果存在则取出来,如果不存在则添加进去。具体详细使用与解析对比还请看http://www.importnew.com/21836.html,这篇博客,个人认为是极好的。通俗易懂。


4.如果看完链接想使用字符串的intern();这个方法。然而每次都要调用,这未免太过于麻烦,考虑到这个因素,博主给诸位提供一个不用掉用也能使用intern();的方法。那就是配置GC,且要使用G1 GC,GC配置是 ‘-XX:+UseStringDeduplication’ 。


5.在使用了intern();方法的情况下,尽量不要使用new 方法来创建新的字符串,因为new 方法是直接在堆中创建一个对象,不会去字符串常量池中,进行操作。


6.看下面代码块吧~

   //.java文件:
    public static void main(String args[]){
        String c = "12241241242";
        String b =  UUID.randomUUID().toString().intern();
        String a = "sda"+"123"+b+"sss"+c;
    }

    //.class文件反编译后
    public static void main(String[] args) {
        String c = "12241241242";
        String b = UUID.randomUUID().toString().intern();
        (new StringBuilder()).append("sda123").append(b).append("sss").append(c).toString();
    }

博文部分资料来源于:java核心技术36讲。

如果博文有什么错误的地方欢迎指出,非常感谢。如果有相互交流的欢迎交流。最后,感谢每一位程序猿对代码的辛勤付出。

  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值