关于String,StringBuffer和StringBuilder的区别

关于String,StringBuffer和StringBuilder的区别

在高并发的应用场景的时候,这个时候就必须熟悉String,StringBuffer和StringBuilder的区别,如果不需要线程安全的情况, 需要动态拼接字符串的话,大多数的情况下会选择StringBuilder。

针对字符串动态拼接速度,String<StringBuffer<StringBuilder

String为什么最慢

 s1和s2其实是同一个对象,他们在JVM虚拟机中的地址是一样。因为String的hashCode被重写,因此我们需要用System.identityHashCode()获取s1和s2在JVM虚拟机中的地址。在经过s1 = s1 + " World!"后,s1和s2在JVM虚拟机中的地址 不一样,说明s1并没有被改变,其实JVM虚拟机又为s1创建了一个新的对象。所以String的动态拼接实际上JVM虚拟机不断的创建新的对象并且将旧的对象回收的一个过程,所以速度很慢。

测试代码

String s1 = "Hello";
String s2 = s1;
System.out.println(s1);
System.out.println(Integer.toHexString(System.identityHashCode(s1)));
System.out.println(Integer.toHexString(System.identityHashCode(s2)));
s1 = s1 + " World!";
System.out.println(s1);
System.out.println(Integer.toHexString(System.identityHashCode(s1)));
System.out.println(Integer.toHexString(System.identityHashCode(s2)));

测试结果

Hello
1540e19d
1540e19d
Hello World!
677327b6
1540e19d

StringBuffer和StringBuilder对象是变量,在字符串动态拼接的时候,直接更改对象,不对对象进行创建和回收,所以速度快。

StringBuffer线程安全,StringBuilder线程不安全

StringBuffer的append源码

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

StringBuilder的append源码

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

他们的都同时继承同一个父类,java.lang.AbstractStringBuilder

append的源码

   /**
     * Appends the specified string to this character sequence.
     * <p>
     * The characters of the {@code String} argument are appended, in
     * order, increasing the length of this sequence by the length of the
     * argument. If {@code str} is {@code null}, then the four
     * characters {@code "null"} are appended.
     * <p>
     * Let <i>n</i> be the length of this character sequence just prior to
     * execution of the {@code append} method. Then the character at
     * index <i>k</i> in the new character sequence is equal to the character
     * at index <i>k</i> in the old character sequence, if <i>k</i> is less
     * than <i>n</i>; otherwise, it is equal to the character at index
     * <i>k-n</i> in the argument {@code str}.
     *
     * @param   str   a string.
     * @return  a reference to this object.
     */
    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

StringBuffer的方法上有synchronized,因此在多个线程使用的时候StringBuffer是线程安全的,而StringBuilder不是线程安全的。

测试:

public class MyTestString {

    public static final int COUNT = 10000000;

    private static void test1() {
        String str = "";
        long beginTime=System.currentTimeMillis();
        for(int i=0;i<COUNT;i++){
            str = "Hello" + "world";
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-beginTime);
    }

    private static void test2() {
        String s1 = "hello";
        String s2 = "world";
        String str = "";
        long beginTime=System.currentTimeMillis();
        for(int i=0;i<COUNT;i++){
            str = s1 + s2;
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-beginTime);
    }

    private static void test3() {
        String s1 = "hello";
        String str = "";
        long beginTime=System.currentTimeMillis();
        for(int i=0;i<10000;i++){
            str = str + s1;
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-beginTime);
    }

    private static void test4() {
        String s1 = "hello";
        StringBuilder str = new StringBuilder();
        long beginTime=System.currentTimeMillis();
        for(int i=0;i<COUNT;i++){
            str = str.append(s1);
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-beginTime);
    }

    private static void test5() {
        String s1 = "hello";
        StringBuffer str = new StringBuffer();
        long beginTime=System.currentTimeMillis();
        for(int i=0;i<COUNT;i++){
            str = str.append(s1);
        }
        long endTime=System.currentTimeMillis();
        System.out.println(endTime-beginTime);
    }

    public static void main(String[] args) {
        test1();
        test2();
        test3();
        test4();
        test5();
    }
}

测试结果:

5    //String
388  //String
486  //String
261  //StringBuilder
751  //StringBuffer


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值