String、StringBuffer和StringBuilder的区别

版权声明:本文出自孤星卟哭的博客,原创文章,转载请注明出处。 https://blog.csdn.net/zcy92949/article/details/79917346

前言

对于这三者,当初学习的时候一直都是很蒙的,因为一直用的都是String,所以直到这次整理笔记,才重新认识了一下他们三个。

1、String为什么运行速度最慢?

记得当初学习的时候,老师总是说String一旦创建,不可修改,可是有一次自己实验,却发现如下代码改变了,为什么会有这样的错觉呢?

String str = "This a Aima";      
str = "This a Aima Student";

上述代码输出str结果会变成This a Aima Student。其实这只是JVM(虚拟机)的一个垃圾回收机制,第一行代码的内容创建,真实的情况是,JVM会先去常量池寻找是否有This a Aima,如果有,将str指向This a Aima,否则在常量池中创建This a Aima,之后将str指向This a Aima;第二行代码的内容创建,同上描述,只不过最后会把str指向This a Aima Student,这时This a Aima作为用不到的数据,定时就会被JVM的垃圾回收机制回收,因此,str之前指向的内容并没有改变,只不过JVM重新创建了新的内容,并且改变了str的指向。而StringBuffer和StringBuilder无论怎样修改都是在原内容的基础上修改。String不断的创建、回收,这也就是为什么String运行速度最慢的原因。

2、StringBuffer和StringBuilder的线程安全问题

如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized(单例模式经常用到的关键字,我喜欢称之为线程锁)关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。

3、String和StringBuffer的一些代码举例

这是去年二月十四号总结的一些String常用方法,以及和StringBuffer的比较

public void getSummary() {
    /*
     * String类的演示;String无论经过怎样变化,最初的内容不变
     */
    // 字符串
    String str = "This a Aima";

    // 长度
    System.out.println("length: " + str.length());

    // 位置
    System.out.println("indexOf: " + str.indexOf("i"));

    // 指定字符最后一次出现的位置
    System.out.println("lastIndexOf: " + str.lastIndexOf("i"));

    // 比较
    String str1 = "this";
    if (!str1.equals(str)) {
        System.out.println("equals: " + false);
    }

    // 取指定字符
    System.out.println("charAt: " + str.charAt(3));

    // 取字符串两种方法[)
    System.out.println("substring: " + str.substring(5, 8));

    char[] chArray = new char[10];
    str.getChars(7, 10, chArray, 0);// 从字符串str中取得从3到7的字符串放
                                    // 入cArray数组中并从数组中的0位置开始存放
    System.out.print("getChars: ");
    for (int i = 0; i < chArray.length; i++) {
        System.out.print(chArray[i]);
    }
    System.out.println();

    // 字符操作
    // 取代操作
    System.out.println("replace: " + str.replace('a', 'A'));

    // 合并操作
    String str2 = "Academy";
    String str7 = str.concat(str2);
    System.out.println("concat: " + str7);

    // 大小写转换
    str.toLowerCase();// 全体小写
    str.toUpperCase();// 全体大写

    // 类型转换,可以将任何类型转换成字符串
    double dbl = 999;
    String str3 = String.valueOf(dbl);
    System.out.println("将浮点型转换成字符串: " + str3);

    /*
     * StringBuffer类的演示;StringBuffer内容一旦改变,其中的内容就随之而不断变化了
     */
    StringBuffer str4 = new StringBuffer("This a Aimaonline");

    // 改变其中一个字符;因为setCharAt()方法无返回值,所以不能在输出中边执行边输出
    str4.setCharAt(2, 'b');
    System.out.println("setCharAt: " + str4);

    // 追加字符
    System.out.println("append: " + str4.append("accmary"));

    // 指定位置追加字符
    System.out.println("insert: " + str4.insert(2, "w"));

    // 删除我们指定的一段字符串[)
    System.out.println("delete: " + str4.delete(5, 7));

    // 字符串分割 , 用"空格"将"This a Aima"分割为3部分
    // 并将字符串存储到字符串数组中
    String[] strArray = str.split(" ");
    System.out.println("split: ");
    for (int i = 0; i < strArray.length; i++) {
        System.out.println(strArray[i]);
    }

    // 字符比较,比较的是首字母的ASCII码
    String str5 = "this";
    String str6 = "This";
    if (str5.compareTo(str6) > 0) {
        System.out.println("比较的结果是: str5>str6");
    } else {
        System.out.println("比较的结果是: str5<str6");
    }

}

4、三者总结

String:适用于少量的字符串操作的情况;

StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况;

StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况。

5、总结

以上就是我对String、StringBuffer和StringBuilder的理解,如有不对之处,希望诸君不吝赐教。

数组排序、String字符串排序和StringBuffer字符串排序的代码文档在此链接中,有兴趣的可以下载
https://download.csdn.net/download/zcy92949/10345605

猜你喜欢

转载自blog.csdn.net/zcy92949/article/details/79917346
今日推荐