動手動腦4--有關字符串的一些東西
為何會出現這樣的結果?
s0,s1,s2三個String類型的對象實際上指向的都是"Hello"這個常量,所以s0、s1、s2三者之間用==判斷是否指向同一塊內存肯定會返回布爾值true,這裏的s0、s1、s2就很像C/C++裏面的指針(Java官方說是沒有指針的,其實Sun公司在寫Java這門語言時幹脆就把指針給封裝成引用這種類型了,比較C++裏面利用new字段開辟新空間的那句代碼,和Java中利用new字段定義新對象的那句代碼,其實是一樣的,只不過那個*不用寫了),而後面那兩個是實實在在定義的兩個新的不同的對象,盡管存的值相同,但是==對於兩個對象而言比較的是他們指向的空間的地址,所以自然會返回布爾值false
這又有一個新的例子,和上面的區別就是為什麽s1=="ab"會返回false,有人會問s1+="ab",s1="ab",那麽兩者指向不應該一樣嗎?
這個問題有點麻煩,主要就麻煩在s1+="b"這個操作不是在聲明s1時完成的,要是和上面那個例子一樣直接寫String s1 = "a"+"b",那樣還會是true。但是為什麽分開寫就不行呢,這跟String池有關。這個池維護所有不同的實例化後的字符串,比如,可能有a, ab, cde等等。當程序申請一個新的字符串的時候,如果這個字符串已經存在池中,那麽這個字符串就會被返回,如果沒有,就實例化一個新的,並且把它也放到池中。所以String s1 = "a"+"b",執行到這句時,會自動檢查池中有沒有"ab"這個串,如果有就將“ab”這個常量的地址交給s1,所以就解釋了為什麽上面那個例子是true。而這裏這個由於分開了,是在s1+="b"這個過程中完成了s1 = new String("ab")這麽個隱藏的過程,所以這裏是false。至於equals那個方法,這裏不講,下面的例子會重點提到。
接下來就說說String類中一個重要的方法——equals,用來比較兩個字符串的內容是否一樣。
方法的源碼:
1 public boolean equals(Object anObject) { 2 if (this == anObject) { 3 return true; 4 } 5 if (anObject instanceof String) { 6 String anotherString = (String) anObject; 7 int n = value.length;8 if (n == anotherString.value.length) { 9 char v1[] = value; 10 char v2[] = anotherString.value; 11 int i = 0; 12 while (n-- != 0) { 13 if (v1[i] != v2[i]) 14 return false; 15 i++; 16 } 17 return true; 18 } 19 } 20 return false; 21 }
從上面的代碼中可以看到,
(1)String類中的equals首先比較地址,如果是同一個對象的引用,可知對象相等,返回true。
(2)若果不是同一個對象,equals方法挨個比較兩個字符串對象內的字符,只有完全相等才返回true,否則返回false。
參考一段代碼:
String str = "abc";
String str1 = str.trim().toUpperCase().concat("defg");
輸出str1,會顯示"ABCdefg",trim()的作用是去掉字符串首位的空格,toUpperCase()的作用是將小寫字符大寫化,而concat(String s)的作用是將參數s加在字符串的後面,由此可以寫一個MyCounter類,添加兩個方法increase()和decrease(),返回值都是int型(或者利用重載計算多種類型),代碼如下:
1 public class MyCounter{ 2 private int value; 3 public MyCounter(int value){ 4 this.value =value; 5 } 6 public int increase(int val){ 7 value+=val; 8 return value; 9 } 10 public int decrease(int val){ 11 value-=val; 12 return value; 13 } 14 public String toString(){ 15 return String.valueOf(value); 16 } 17 }
MyCounter counter1=new MyCounter(1);
MyCounter counter2=counter1.increase(100).decrease(2).increase(3);
System.out.print(counter1); 在主函數中寫入這些代碼,會輸出102
最後再來說說幾個常用的String類中的常用方法:
public int length():返回值類型為int型,返回當前字符串的有效長度
public void charAt(int num):num為索引值,返回字符串中下標為num的字符,如果越界會拋出異常
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin):截取字符數組,要復制的第一個字符在索引srcBegin處,被復制的最後一個字符是在的索引srcEnd1即要復制的字符總數是srcEnd srcBegin處。字符被復制到子數組的夏令時開始在指數dstBegin和結束於索引:dstbegin + (srcEnd-srcBegin) - 1
public String replace(char oldChar,char newChar):替換字符,利用newchar替換oldchar,然後返回新的字符串
UpperCase()和toLoserCase()一個轉成大寫,一個轉成小寫
trim():去掉字符串首尾兩端所有的空格
至於toCharArray(),上源碼:
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
將一個字符串轉換成一個Char型的字符數組,並且這裏面的字符是原封不動的拿進去的,意思就是說,包含一切字符均轉換成相應的字符數組。
==========================================================================================================================================================================
End
動手動腦4--有關字符串的一些東西