11 为什么会有String,StringBuffer,StringBuilder及区别?耗时比较


为什么会有String?


String是字符串的意思。但是是否注意到String首字母是大写呢,一般什么才会首字母大写?当然是类了。

String类表示内容不可改变的字符串。

什么叫不可改变呢?

String str = "abc";
str = "bcd";
System.out.println(str); //输出为bcd

类似于

Person p = new Person();
System.out.println(p.toString()); //输出为com.junc.test.Person@15db9742
p = new Person();
System.out.println(p); //输出为com.junc.test.Person@6d06d69c

两者的P是不同的,所以同理,两者的str也是不同的,说明abc并没有被改变。这就是为什么说String类表示内容不可以改变的字符串。

那么不可变会带来什么样的不好的影响呢?

String s = "hello";
s = s + "world!";

上面这两行代码执行后,原始的String对象中的内容变了没有呢?

答案是没有,因为我们说了String类是不可变类,当执行s = s + "world!"时,只是之前的s不指向原来那个对象了,那个对象还在内存中。那么使用String来代表字符串的话会引起很大的内存开销,就会导致内存消耗过多而使程序运行的非常慢,也就是手机或电脑常出现的卡机现象。


怎么办呢?为什么会有StringBuffer?


我们想到了一种办法,就是再设计一个可变的,这样就不用每次再创建新的对象而制造垃圾了。命名为StringBuffer。Buffer是缓冲区的意思,也就是说将String放入一个缓冲区,在这个区域内不断改变字符串就可以了。

package com.junc.test;

public class TestString3 {

    public static void main(String[] args) {
        StringBuffer sb = new StringBuffer();
        StringBuffer sb1 = sb.append("a");
        StringBuffer sb2 = sb.append("b");

        System.out.println(sb1); //输入出ab
    }
}

当打印sb1而不是sb2的时候,输出结果是ab。这就代表着StringBuffer是一个改变的,共用了一个缓冲区,在这个缓冲区内进行操作,如此效率才高。

当然,一个初步的新生事物,我们是要保证安全的。

故StringBuffer是线程安全的,并且是可变的字符序列。


为什么会有StringBuilder?


在我们的生活中,安全代表着什么?为了安全,我们加了一道门。为了安全,我们加了一个锁,但要是你有急事,想快点回家拿个东西,是不是还要先拿钥匙,找到钥匙,打开门才行。这样效率是不是显得很低。

那么怎么提高效率呢?不要安全了,不要门,可以直接进去拿东西。
为了应对这样情况,我们又创建了一个新的类:StringBuilder.
它是线程不安全的,但运行效率会比StringBuffer更高。

所以,在不存在不安全情况的时候,我们还是要选择StringBuilder。
但晚上睡觉,存在不安全情况的时候,我们还是要选择StringBuffer。

耗时比较:

package com.junc.test1;

public class Test1 {

    public static void main(String[] args) {

        //StringBuffer用时
        long start1 = System.currentTimeMillis();

        StringBuffer sb1 = new StringBuffer();
        for(int i = 0; i < 1000000; i++) {
            sb1.append(i).append(" ");
        }

        long end1 = System.currentTimeMillis();
        System.out.println(end1 - start1); //输出78

        //StringBuilder用时
        long start2 = System.currentTimeMillis();

        StringBuilder sb2 = new StringBuilder();
        for(int i = 0; i < 1000000; i++) {
            sb2.append(i).append(" ");
        }

        long end2 = System.currentTimeMillis();
        System.out.println(end2 - start2);//输出31
    }
}

总结:

  • String是不可变的字符序列。

  • StringBuffer是线程安全的,可变的字符序列,效率比String高。

  • StringBuilder是线程不安全的,可变的字符序列,效率比StringBuffer更高。

你可能感兴趣的:(00,java基础)