String、StringBuffer和StringBuilder区别

一、String

       String是不可变对象,即对象一旦生成,就不能被更改。对String对象的任何改变会引发新的String对象的生成。

       这点可以从String源码中的一些方法中去理解:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

  public String substring(int beginIndex, int endIndex) {

    if (beginIndex < 0) {

        throw new StringIndexOutOfBoundsException(beginIndex);

    }

    if (endIndex > count) {

        throw new StringIndexOutOfBoundsException(endIndex);

    }

    if (beginIndex > endIndex) {

        throw new StringIndexOutOfBoundsException(endIndex - beginIndex);

    }

    return ((beginIndex == 0) && (endIndex == count)) ? this :

        new String(offset + beginIndex, endIndex - beginIndex, value);

    }

    }

 public String concat(String str) {

    int otherLen = str.length();

    if (otherLen == 0) {

        return this;

    }

    char buf[] = new char[count + otherLen];

    getChars(0, count, buf, 0);

    str.getChars(0, otherLen, buf, count);

    return new String(0, count + otherLen, buf);

 }

 

 public String replace(char oldChar, char newChar) {

    if (oldChar != newChar) {

        int len = count;

        int i = -1;

        char[] val = value; /* avoid getfield opcode */

        int off = offset;   /* avoid getfield opcode */

 

        while (++i < len) {

        if (val[off + i] == oldChar) {

            break;

        }

        }

        if (i < len) {

        char buf[] = new char[len];

        for (int j = 0 ; j < i ; j++) {

            buf[j] = val[off+j];

        }

        while (i < len) {

            char c = val[off + i];

            buf[i] = (c == oldChar) ? newChar : c;

            i++;

        }

        return new String(0, len, buf);

        }

    }

    return this;

  }

   

二、StringBuffer

StrinhBuffer:每次都对对象本身进行操作,而不是生成新的对象。所以在字符串内容不断改变的情况,建议使用StringBuffer。

String对象的字符串拼接其实是被JVM解释成了StringBuffer对象的拼接,所以这些时候String对象的速度并不会比StringBuffer慢。

例如:如下代码,String的效率远比StringBuffer快。

1  String S1 = “This is only a” + “ simple” + “ test”; 
2  StringBuffer Sb = new StringBuilder(“This is only a”).append(“simple”).append(“ test”); 

这是因为,在JVM眼里:String S1 = “This is only a” + “ simple” + “ test”;就是String S1 = “This is only a simple test”;

三、StringBuilder

StringBuilder是与StringBuffer具有相同的操作。

区别在于:StringBuffer是线程安全的类。StringBuilder不是线程安全的类,在单线程中性能要比StringBuffrer高。

例如:《Think in Java》中,描述HashTable和HashMap区别一样,就是因为HashTable支持线程同步、保证线程安全而导致的性能下降。

  HashTable是线程安全的,很多方法都是synchronized方法。

  HashMap不是线程安全的,但在单线程程序中的性能比HashTable要高。

 

StringBuffer 和 StringBuider 可以从下面两端源码来体会其设计区别:

   StringBuilder的insert方法

1

2

3

4

5

6

public StringBuilder insert(int index, char str[], int offset,

                              int len)

  {

      super.insert(index, str, offset, len);

  return this;

  }

  StringBuffer的insert方法:

1

2

3

4

5

6

public synchronized StringBuffer insert(int index, char str[], int offset,

                                            int len)

    {

        super.insert(index, str, offset, len);

        return this;

    }

四、总结一下

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

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

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

你可能感兴趣的:(Java)