天天看點

String 、StringBuffer 與StringBuilder的異同

String 、StringBuffer 與StringBuilder的異同詳解

在聲明方面:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence      
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence      
public final class StringBuffer
   extends AbstractStringBuilder
   implements java.io.Serializable, CharSequence      

String、StringBuffer、StringBuilder都實作了CharSequence接口和Serializable接口 ;

String、StringBuffer、StringBuilder都是final不可繼承和重寫;

String實作了字元串比較的Comparable接口;

StringBuffer和StringBuilder都繼承AbstractStringBuilder抽象類;

在字元串拼接效率上:

String<StringBuffer<StringBuilder,但是如果是String str=“a”+“b”+“c“是效率最高的。因為”a“、”b“、”c“都在字元串常量池裡面。就是直接在常量池将a、b、c拼接成abc再放入字元串常量池。

如果沒有這三句指派String s1=”a”;String s2=”b”;String s3=”c”;

String str=“a”+“b”+“c“;這句語句會生成4個新對象均放入字元串常量池中

如圖:

String 、StringBuffer 與StringBuilder的異同

測試如圖

public static void main(String[] args) {
        StringBuilder strB = new StringBuilder();
  //      String str = new String();
        String a1 = "1";
        String b1 = "2";
        String c1 = "3";
        String d1 = "3";
        String e1 = "3";
        String f1 = "3";
        String g1 = "3";
        String h1 = "3";
        String i1 = "3";

        long startTime = System.nanoTime();
//        strB.append(a1).append(b1).append(c1).append(d1).append(e1).append(f1).append(g1).append(h1).append(i1);
//        strB.append(a1);strB.append(b1);strB.append(c1);strB.append(d1);
//        strB.append(e1);strB.append(f1);strB.append(g1);strB.append(h1);strB.append(i1);
        strB.append("a").append("b").append("c").append("d").append("e").append("f").append("g").append("h").append("i");
        long endTime = System.nanoTime();
        System.out.println(endTime-startTime);


        long startTime1 = System.nanoTime();
//        str +=a1;str +=b1;str +=c1;str +=d1;str +=e1;str +=f1;str +=g1;str +=h1;str +=i1;
//        str = a1 + b1 + c1 + d1 + e1 + f1 + g1 + h1 + i1;
        String str = "j"+"k"+"l"+"m"+"n"+"o"+"p"+"q"+"r";
        long endTime1 = System.nanoTime();
        System.out.println(endTime1-startTime1);
    }      

第一行是StringBuilder,第二行String。

String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同

顯然String的操作快很多。

而如果是類似下圖的String拼接(其實質是通過StringBuilder的append方法來拼接,但是每次都會傳回一個String對象,存放在堆中)。可以通過IDE的debug的Force step into調試看出來。

public static void main(String[] args) {
        StringBuilder strB = new StringBuilder();
        String str = new String();
        String a1 = "1";
        String b1 = "2";
        String c1 = "3";
        String d1 = "3";
        String e1 = "3";
        String f1 = "3";
        String g1 = "3";
        String h1 = "3";
        String i1 = "3";

        long startTime = System.nanoTime();
//        strB.append(a1).append(b1).append(c1).append(d1).append(e1).append(f1).append(g1).append(h1).append(i1);
        strB.append(a1);strB.append(b1);strB.append(c1);strB.append(d1);
        strB.append(e1);strB.append(f1);strB.append(g1);strB.append(h1);strB.append(i1);
        long endTime = System.nanoTime();
        System.out.println(endTime-startTime);


        long startTime1 = System.nanoTime();
        str +=a1;str +=b1;str +=c1;str +=d1;str +=e1;str +=f1;str +=g1;str +=h1;str +=i1;
        long endTime1 = System.nanoTime();
        System.out.println(endTime1-startTime1);
    }      

 第一行是StringBuilder,第二行String。

String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同

其主要是在字元串拼接過程中StringBuilder不會生成新的StringBuilder對象,而String每次都會生成新String對象放入堆記憶體中,雖然他們的拼接都是用StringBuilder的方法。

也是以,如果是如下圖的String的字元串拼接,就會發現如果兩者字元串拼接效率是相近的。

public static void main(String[] args) {
        StringBuilder strB = new StringBuilder();
        String str = new String();
        String a1 = "1";
        String b1 = "2";
        String c1 = "3";
        String d1 = "3";
        String e1 = "3";
        String f1 = "3";
        String g1 = "3";
        String h1 = "3";
        String i1 = "3";

        long startTime = System.nanoTime();
//        strB.append(a1).append(b1).append(c1).append(d1).append(e1).append(f1).append(g1).append(h1).append(i1);
        strB.append(a1);strB.append(b1);strB.append(c1);strB.append(d1);
        strB.append(e1);strB.append(f1);strB.append(g1);strB.append(h1);strB.append(i1);
        long endTime = System.nanoTime();
        System.out.println(endTime-startTime);


        long startTime1 = System.nanoTime();
//        str +=a1;str +=b1;str +=c1;str +=d1;str +=e1;str +=f1;str +=g1;str +=h1;str +=i1;
        str = a1 + b1 + c1 + d1 + e1 + f1 + g1 + h1 + i1;
        long endTime1 = System.nanoTime();
        System.out.println(endTime1-startTime1);
    }      

第一行是StringBuilder,第二行String。

String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同

StringBuilder的構造預設容量為16

public StringBuilder() {
    super(16);
}      

如下圖是StringBuilder的父類AbstractStringBuilder裡面的的擴容方法,

把 (長度)×2+2;

private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int newCapacity = (value.length << 1) + 2;
    if (newCapacity - minCapacity < 0) {
        newCapacity = minCapacity;
    }
    return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
        ? hugeCapacity(minCapacity)
        : newCapacity;
}      

StringBuffer與StringBuilder差不多,因為StringBuffer也是繼承抽象類

AbstractStringBuilder,是以StringBuffer在與String類型字元串拼接效率上比較也是比String類型的要快。其次就是跟StringBuilder比較主要是StringBuffer的大多數方法加了syncronized關鍵字,也是以StringBuffer是線程安全的,StringBuilder是非線程安全的。

public static void main(String[] args) {
    String a1 = "1";
    String b1 = "2";
    String c1 = "2";
    String d1 = "3";
    String e1 = "3";
    String f1 = "3";
    String g1 = "3";
    String h1 = "3";
    String i1 = "3";
    StringBuilder sbd = new StringBuilder();
    StringBuffer sb = new StringBuffer();

    long startTime = System.nanoTime();
    sbd.append(a1);sbd.append(b1);sbd.append(c1);sbd.append(d1);
    sbd.append(e1);sbd.append(f1);sbd.append(g1);sbd.append(h1);sbd.append(i1);
    long endTime = System.nanoTime();
    System.out.println(endTime - startTime);


    long startTime1 = System.nanoTime();
    sb.append(a1);sb.append(b1);sb.append(c1);sb.append(d1);
    sb.append(e1);sb.append(f1);sb.append(g1);sb.append(h1);sb.append(i1);
    long endTime1 = System.nanoTime();
    System.out.println(endTime1 - startTime1);
}      

第一行是StringBuilder的,第二行是Stringbuffer的

String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同
String 、StringBuffer 與StringBuilder的異同

發現其實差不多,是以線程安全的情況下用StringBuilder,非線程安全用StringBuffer。主要還是具體情況具體分析。