1. 程式人生 > >你所不知道的String(String系列一)

你所不知道的String(String系列一)

String

1、String定義

技術分享圖片


>通過源碼,String是由final修飾的,不能被繼承,實現序列化,其中序列化的標識是由定義的變量處理,serialVersionUID和serialPersistentFields。其中另外兩個變量是char數組和hash。

![](http://i2.51cto.com/images/blog/201804/03/2f2f3120638ef0b84fcb77fc6bc4e4bd.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)

### 2、String 構造函數
>String的構造方法,一共是15個,
>8個是字節數組參數(大部分實現是由StringCoding.decode()實現),
>1個是int數組(  分配一個新的 String,它包含 Unicode 代碼點數組參數一個子數組的字符),
>
>1個無參,1個原始,
>1個Stringbuffer ,1個Stringbuilder,兩者都是通過Arrays.copyOf()實現,其中buffer是使用synchronized(buffer)加鎖
>2個char數組(通過Arrays.copyOf()實現)。

### 3、 String的基本方法
>1個本地方法,

 public native String intern();
>15個靜態公共方法包含

copyValueOf(char[]), valueOf(),format(String, Object...),join()

>50個常用公共方法;
>重點是排序算法compareTo()、hash算法( h = 31 * h + val[i];)

```
public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
```

>s[i] 是string的第i個字符,n是String的長度。那為什麽這裏用31,而不是其它數呢?《Effective Java》是這樣說的:之所以選擇31,是因為它是個奇素數,如果乘數是偶數,並且乘法溢出的話,信息就會丟失,因為與2相乘等價於移位運算。使用素數的 好處並不是很明顯,但是習慣上都使用素數來計算散列結果。31有個很好的特性,就是用移位和減法來代替乘法,可以得到更好的性能:31*i==(i<<5)-i。現在的VM可以自動完成這種優化。

```

public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
```
> 首先取出兩個字符串的長度,比較較小的長度內,兩者是否相等。
若不相等,則直接返回該位置字符的ASCII碼相減後的值。
  若各位置都相等,則將兩個字符串長度的差值返回

你所不知道的String(String系列一)