首页 > 代码库 > 每天一道Java题[5]

每天一道Java题[5]

题目

String、StringBuilder、StringBuffer有什么异同?

   

解答

相同点:String、StringBuilder、StringBuffer都可以用来存储字符串。

不同点:

1、String与StringBuilder、StringBuffer的不同点主要在于,String对象创建之后,是不可改变的,平时我们对同一个String变量赋值,实际上是创建了个新的对象。而后两者是可变的,这意思就是说,他们可以在同一内存地址上更改它的值,而无需创建新的对象。

2、StringBuilder与StringBuffer的不同点在于,StringBuffer是线性安全的,但是它比StringBuilder要慢。

   

参考代码

StringBufferThreadSafeTest

 

package me.huangzijian;

public class StringBufferThreadSafeTest {

    public static void main(String[] args) {

        //测试StringBuffer线程安全部分
        String s = "123456789";  
        StringBuffer stringBuffer = new StringBuffer(s);  
        StringBuilder stringBuilder = new StringBuilder(s);  

        SbfReverseThread sbfRT1 = new SbfReverseThread(stringBuffer);  
        SbfReverseThread sbfRT2 = new SbfReverseThread(stringBuffer);  
        SbdReverseThread sbdRT1 = new SbdReverseThread(stringBuilder);  
        SbdReverseThread sbdRT2 = new SbdReverseThread(stringBuilder);  

        new Thread(sbfRT1).start();  
        new Thread(sbfRT2).start();  
        new Thread(sbdRT1).start();  
        new Thread(sbdRT2).start();  
        
        //测试StringBuffer比StringBuilder慢部分,注意不要同时运行两个循环,一次运行一个,这样才精确
        long startTime2 = System.currentTimeMillis(); 
        for (int i = 0; i <= 10000000; i++) {
            stringBuffer.reverse();
        }
        long endTime2 = System.currentTimeMillis();
        System.out.println("StringBuffer循环1000次所需时间:" + (endTime2 - startTime2) + "ms");
        
        long startTime1 = System.currentTimeMillis(); 
        for (int i = 0; i <= 10000000; i++) {
            stringBuilder.reverse();
        }
        long endTime1 = System.currentTimeMillis();
        System.out.println("StringBuilder循环1000次所需时间:" + (endTime1 - startTime1) + "ms");
    }
}

 

 

SbfReverseThread

package me.huangzijian;

public class SbfReverseThread implements Runnable {

    StringBuffer stringBuffer;

    public SbfReverseThread(StringBuffer stringBuffer) {
        this.stringBuffer = stringBuffer;
    }

    @Override
    public void run() {
        for (int i = 0; i <= 1000; i++) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stringBuffer.reverse();
            System.out.println("StringBuffer:" + stringBuffer);
        }
    }
}

SbdReverseThread

package me.huangzijian;

public class SbdReverseThread implements Runnable {

    StringBuilder stringBuilder;

    public SbdReverseThread(StringBuilder stringBuilder) {
        this.stringBuilder = stringBuilder;
    }

    @Override
    public void run() {
        for (int i = 0; i <= 1000; i++) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stringBuilder.reverse();
            System.out.println("StringBuilder:" + stringBuilder);
        }
    }
}

   

从结果可以看出:

1.StringBuilder对于字符串123456789,两个线程运行到一段时间,就开始混乱,不再是123456789或者987654321了,而StringBuffer无论重复多少次,依然是123456789或者987654321。

2.我机器上,StringBuffer字符串反转运行10000000,用时370ms足有,而StringBuilder字符串反转运行10000000,只需要150ms左右,可见StringBuilder比StringBuffer快。

   

   

每天一道Java题[5]