你所不知道的String(String系列一)
阿新 • • 發佈:2018-04-08
String1、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系列一)