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;}
?
?
?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拼接的效率較高。
?