一、概述
Java是以String類型的對象來實現字符串。String是一個類,當創建一個String對象后,所創建的字符串是不能改變的。在需要使用可修改的字符串時,Java提供兩個選擇—StringBuffer和StringBuilder。注:聲明為String引用的變量在任何時候都可以改變,以指向一些其他的String對象。
二、String構造函數
String s1="hello"與String s2=new String("hello")的區別:
String類在內存中管理一個字符串常量池(常量池的一部分),池中所有相同的字符串常量被合並,只占用一個空間。
String s1=”hello”,先看池中有沒有hello,沒有就創建一個hello字符串對象。即采用此方法創建0或者1個對象。
String s2=new String(“hello”),這里先在池中創建一個hello對象,同s1,然后new String()時,將hello對象復制到堆heap中,s2指向堆中的hello。采用此種方法時創建1或2個對象(當池中有hello時,創建一個對象)。
內存圖如下:
三、String類的方法函數
String類有很多方法,這里只介紹幾種常見的函數:
1、字符串的長度:
int length();
2、字符串轉換
每個類都會實現toString方法,因為它是由Obect定義的,對於大多數的自創建的類來說,通常要重寫toString()並提供自己的字符串表達式。
eg:
1 class Box 2 { 3 int x; 4 int y; 5 Box(int x,int y) 6 { 7 this.x=x; 8 this.y=y; 9 } 10 public String toString() 11 { 12 return "test_x"+"-----"+x+"\n"+"test_y"+"-----"+y; 13 } 14 } 15 public class Tset 16 { 17 public static void main(String[] args) 18 { 19 Box b=new Box(1,3); 20 System.out.println(b); 21 } 22 23 }
顯示結果為:
疑問:看了一下println的源碼,不知道此處輸出結果為何是如此?
1 private void write(String s) { 2 try { 3 synchronized (this) { 4 ensureOpen(); 5 textOut.write(s); 6 textOut.flushBuffer(); 7 charOut.flushBuffer(); 8 if (autoFlush && (s.indexOf('\n') >= 0)) 9 out.flush(); 10 } 11 } 12 catch (InterruptedIOException x) { 13 Thread.currentThread().interrupt(); 14 } 15 catch (IOException x) { 16 trouble = true; 17 } 18 }
3、字符抽取
charAt(): 返回指定索引處的 char 值。 getChars():一次抽取多個字符。 getBytes():將字符存儲在字節數組里。
4、字符串比較
equals()和==:equals()方法是比較String對象中的字符,“==”運算符是比較兩個對象是否引用同一實例。
eg:
1 public class Test 2 { 3 public static void main(String[] args) 4 { 5 String s1=new String("hello");//創建2個對象,一個pool和一個堆里面 6 String s2="hello";//創建1個對象,s2指向pool里面的"hello"對象 7 String s3="hello";//創建0個對象,指向s2指向pool里面的那個對象 8 String s4=s2;//創建0個對象,指向s2,s3指向pool里面的那個對象 9 String s5=new String("hello");//創建1個對象在堆里面,注意,與s1沒關系 10 11 System.out.println(s2=="hello");//true 12 System.out.println(s2==s3);//true,因為指向的都是pool里面的那個"hello" 13 System.out.println(s2==s4);//true,同上,那么s3和s4...:) 14 System.out.println(s1==s5);//false,很明顯,false 15 System.out.println(s1==s2);//false,指向的對象不一樣 16 System.out.println(s1=="hello");//false 17 System.out.println("---------------"); 18 s1=s2; 19 System.out.println(s1=="hello");//true 20 } 21 }
執行結果:
boolean startsWith(String prefix):判斷給定的String是否以特定的字符串開始。 boolean startsWith(String prefix,int toffset):判斷此字符從指定索引開始的字符串是否以指定的前綴開始。 endsWith():判斷給定的String是否是以特定的字符串結束。 compareTo():用於比較字符串大小,並考慮大小寫字母。 compareIgnoreCase():比較字符串大小並忽略大小寫字母。
5、查找字符串
isdexOf():查找字符或子串第一次出現的位置
lastIndexOf():查找字符或者子串最后出現的位置
6、更改字符串
因為String對象是不能改變的,當需要更改一個字符串時,就必須將他復制到一個StringBuffered中,后者使用下列方法,在更改后會構造一個新的字符串副本。
substring(int startIndex):返回從startIndex開始到調用字符串結束的子串的一個副本 substring(int startIndex,int endIndex),指定起點和終點,返回這中間的字符串,不包括終點。 concat():連接兩個字符串,與“+”運算符相同。 replace(char originial,char replacement):用一個字符在調用字符串中所有出現另一個字符的地方進行替換。 replace(CharSequence originial,CharSequence replacement):用一個字符串序列替換另一個字符串序列。 trim():返回調用字符串對象的一個副本,但是所有起始和結尾的空白符都被刪除了(字符中間的空白符未被刪除)。
7、改變字符串中字符的大小寫
toLowerCase():將所有字符改為小寫
toUpperCase():將所有字符改為大寫
四:StringBuffer類
StringBuffer是String的一個對等類,提供了字符串的許多功能,可增長、可改寫。
這里只介紹幾個StringBuffer類的方法函數:
1、append():將任何數據類型的字符串表示連接到調用的StringBuffer對象的末尾。
當定String對象使用“+”運算符時,經常要調用append方法。
StringBuffer s=new StringBuffer("hello"); System.out.print(s.append(" world"));
2、inser(int index,String str):將一個字符串插入到另一個字符串中。
3、reverse():顛倒StringBuffer對象中的字符
4、delete(int startIndex,int endIndex),delete(int loc):調用對象中刪除一串字符。
五、StringBuilder類
除了一個重要的區別之外,與StringBuffer等同,這個區別是他不是同步的,意味着他不是線程安全的,其優勢是更快的性能,在使用多線程時必須使用StringBuffer。