1. 程式人生 > >動手動腦4--有關字符串的一些東西

動手動腦4--有關字符串的一些東西

issue 內存 length 字段 def obj 地址 夏令時 都是

技術分享

為何會出現這樣的結果?

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--有關字符串的一些東西