帶你了解一篇java String部分原始碼解讀,隨著小編來看吧
String類型的成員變數
/** String的属性值 */ private final char value[]; /** The offset is the first index of the storage that is used. */ /**数组被使用的开始位置**/ private final int offset; /** The count is the number of characters in the String. */ /**String中元素的个数**/ private final int count; /** Cache the hash code for the string */ /**String类型的hash值**/ private int hash; // Default to 0 /** use serialVersionUID from JDK 1.0.2 for interoperability */ private static final long serialVersionUID = -6849794470754667710L;
有上面的成員變數可以知道String類別的值是final類型的,不能改變的,所以只要一個值改變就會產生一個新的String類型對象,儲存String資料也不一定從陣列的第0個元素開始的,而是從offset所指的元素開始。
如下面的程式碼是產生了一個新的對象,最後的到的是一個新的值為「bbaa」的新的String的值。
String a = new String("bb"); String b = new String("aa"); String c = a + b;
也可以說String類型的物件是長度不可變的,String拼接字串每次都要產生一個新的對象,所以拼接字串的效率肯定沒有可變長度的StringBuffer和StringBuilder快。
然而下面這種情況卻是很快的拼接兩個字串的:
String a = "aa" + "bb";
原因是:java對它字串拼接進行了小小的優化,他是直接把“aa”和“bb”直接拼接成了“aabb”,然後把值賦給了a,只需生成一次String對象,比上面那種方式減少了2次生成String,效率明顯要高很多。
下面我們來看看String的幾個常見的建構方法吧
1、無參數的建構方法:
public String() { this.offset = 0; this.count = 0; this.value = new char[0]; }
2、傳入一個Sring型別物件的建構方法
public String(String original) { int size = original.count; char[] originalValue = original.value; char[] v; if (originalValue.length > size) { // The array representing the String is bigger than the new // String itself. Perhaps this constructor is being called // in order to trim the baggage, so make a copy of the array. int off = original.offset; v = Arrays.copyOfRange(originalValue, off, off+size); } else { // The array representing the String is the same // size as the String, so no point in making a copy. v = originalValue; } this.offset = 0; this.count = size; this.value = v; }
3、傳入一個字元陣列的建構子
public String(char value[]) { int size = value.length; this.offset = 0; this.count = size; this.value = Arrays.copyOf(value, size); }
4、傳入一個字串數字,和開始元素,元素個數的建構子
public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.offset = 0; this.count = count; this.value = Arrays.copyOfRange(value, offset, offset+count); }
由上面的幾個常見的建構子可以看出,我們在產生一個String物件的時候必須對該物件的offset、count、value三個屬性進行賦值,這樣我們才能得到一個完成的String類型。
常見函數:
1、判斷兩個字串是否相等的函數(Equal):其實就是先判斷比較的實例是否是String類型數據,不是則回傳False,是則比較他們每一個字元元素是否相同,如果都相同則回傳True,否則回傳False
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = count; if (n == anotherString.count) { char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } return true; } } return false; }
2、比較兩個字串大小的函數(compareTo ):輸入是兩個字串,傳回的0代表兩個字串值相同,傳回小於0則是第一個字串的值小於第二個字串的值,大於0則表示第一個字串的值大於第二個字串的值。
比較的過程主要如下:從兩個字串的第一個元素開始比較,實際比較的是兩個char的ACII碼,加入有不同的值,就傳回第一個不同值的差值,否則回傳0
public int compareTo(String anotherString) { int len1 = count; int len2 = anotherString.count; int n = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int i = offset; int j = anotherString.offset; if (i == j) { int k = i; int lim = n + i; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } } else { while (n-- != 0) { char c1 = v1[i++]; char c2 = v2[j++]; if (c1 != c2) { return c1 - c2; } } } return len1 - len2; }
View Code
3、判斷字串是否以prefix字串開頭,toffset是相同的長度
public boolean startsWith(String prefix, int toffset) { char ta[] = value; int to = offset + toffset; char pa[] = prefix.value; int po = prefix.offset; int pc = prefix.count; // Note: toffset might be near -1>>>1. if ((toffset < 0) || (toffset > count - pc)) { return false; } while (--pc >= 0) { if (ta[to++] != pa[po++]) { return false; } } return true; } public int hashCode() { int h = hash; if (h == 0) { int off = offset; char val[] = value; int len = count; for (int i = 0; i < len; i++) { h = 31*h + val[off++]; } hash = h; } return h; }
4、連接兩個字串(concat)
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); }
連接字串的幾種方式
1、最直接,直接用+連接
String a = new String("bb"); String b = new String("aa"); String c = a + b;
2、使用concat(String)方法
String a = new String("bb"); String b = new String("aa"); String d = a.concat(b);
3、使用StringBuilder
String a = new String("bb"); String b = new String("aa"); StringBuffer buffer = new StringBuffer().append(a).append(b);
第一二中用得比較多,但效率比較差,使用StringBuilder拼接的效率較高。
【相關推薦】
1. java中String是物件還是類別?詳解java中的String
3. Java中String類別的常用方法是什麼?總結Java中String類別的常用方法
以上是分享java String部分源碼解讀的詳細內容。更多資訊請關注PHP中文網其他相關文章!