Java中string類的用法

java中String類的用法

 (2012-12-21 20:51:46)

因爲需要在這裏把String類涉及的各個方面總結一下,另給出了一下SCJP題目。如有不足的地方,請在評論中指教,謝謝。
 
一、不變模式:
一個字符串對象創建後它的值不能改變。
String str1="hello";//創建一個對象hello,不會變;
System.out.println(str1);
str1+=" world!";//兩個字符串對象粘粘,系統其實創建了一個新的對象,把Str1的指向改了,指向新的對象;hello就                     //變成了垃圾;
System.out.println(str1);
//如果一直這樣創建會影響系統的效率;要頻繁的改變字符串對象的值就用StringBuffer來描述;
StringBuffer sb=new StringBuffer("[");
sb.append("hehe");
sb.append("]");//append();不會製造垃圾,真正在改sb的值;
System.out.println(sb);
二、對象池
 
首先要明白,Object obj = new Object();
obj是對象的引用,它位於棧中, new Object() 纔是對象,它位於堆中。
可以這樣理解obj是拴在氫氣球上的繩子,new Object() 是氫氣球,我們通過對象的引用訪問對象,就像我們那着繩子氫氣球纔不會跑掉。
 
 
創建一個Stirng對象,主要就有以下兩種方式:
java 代碼
String str1 = new String("abc");    
Stirng str2 = "abc";  
     雖然兩個語句都是返回一個String對象的引用,但是jvm對兩者的處理方式是不一樣的。對於第一種,jvm會馬上在heap中創建一個String對象,然後將該對象的引用返回給用戶。對於第二種,jvm首先會在內部維護的strings pool中通過String的 equels 方法查找是對象池中是否存放有該String對象,如果有,則返回已有的String對象給用戶,而不會在heap中重新創建一個新的String對象;如果對象池中沒有該String對象,jvm則在heap中創建新的String對象,將其引用返回給用戶,同時將該引用添加至strings pool中。注意:使用第一種方法創建對象時,jvm是不會主動把該對象放到strings pool裏面的,除非程序調用 String的intern方法。看下面的例子:
java 代碼
String str1 = new String("abc"); //jvm 在堆上創建一個String對象   
  
 //jvm 在strings pool中找不到值爲“abc”的字符串,因此   
 //在堆上創建一個String對象,並將該對象的引用加入至strings pool中   
 //此時堆上有兩個String對象   
Stirng str2 = "abc";   //並沒有創建對象,因爲對象池裏已經有"abc" 了
  
 if(str1 == str2){   
         System.out.println("str1 == str2");   
 }else{   
         System.out.println("str1 != str2");   
 }   
  //打印結果是 str1 != str2,因爲它們是堆上兩個不同的對象   
  
  String str3 = "abc";   
 //此時,jvm發現strings pool中已有“abc”對象了,因爲“abc”equels “abc”   
 //因此直接返回str2指向的對象給str3,也就是說str2和str3是指向同一個對象的引用   
  if(str2 == str3){   
         System.out.println("str2 == str3");   
  }else{   
         System.out.println("str2 != str3");   
  }   
 //打印結果爲 str2 == str3  
三、String / StringBuffer / StringBuilder 
 
    String類是字符串常量,是不可更改的常量。而StringBuffer是字符串變量,它的對象是可以擴充和修改的。
 
   StringBuffer sb=new StringBuffer("[");//創建StringBuffer對象
   sb.append("hehe");//把hehe加入字符串,變成 "[hehe"
   sb.append("]");//append();不會製造垃圾,真正在改sb的值;
   System.out.println(sb);
   String str = sb.toString();//把"[hehe]",賦值給一個字符串對象str
    StringBuilder,一個可變的字符序列。此類提供一個與 StringBuffer 兼容的 API,但不保證同步。該類被設計用作StringBuffer 的一個簡易替換,用在字符串緩衝區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因爲在大多數實現中,它比 StringBuffer 要快。
 
StringBuilder sb=new StringBuilder("[");//創建StringBuilder對象
sb.append("hehe");//把hehe加入字符串,變成 "[hehe"
sb.append("]");//append();不會製造垃圾,真正在改sb的值;
System.out.println(sb);
String str = sb.toString();//把"[hehe]",賦值給一個字符串對象str
 
 
四、String類中常用的方法
 
String 類包括的方法可用於檢查序列的單個字符、比較字符串、搜索字符串、提取子字符串、創建字符串副本並將所有字符全部轉換爲大寫或小寫。不用去記,用到的時候查API,用的多了自然就熟悉了。
 
 
  java.lang.String
 char charAt (int index)
 返回index所指定的字符
 String concat(String str)
 將兩字符串連接
 boolean endsWith(String str)
 測試字符串是否以str結尾
 boolean equals(Object obj)
 比較兩對象
 char[] getBytes
 將字符串轉換成字符數組返回
 char[] getBytes(String str)
 將指定的字符串轉成制服數組返回
 boolean startsWith(String str)
 測試字符串是否以str開始
 int length()
 返回字符串的長度
 String replace(char old ,char new)
 將old用new替代
 char[] toCharArray
 將字符串轉換成字符數組
 String toLowerCase()
 將字符串內的字符改寫成小寫
 String toUpperCase()
 將字符串內的字符改寫成大寫
 String valueOf(Boolean b)
 將布爾方法b的內容用字符串表示
 String valueOf(char ch)
 將字符ch的內容用字符串表示
 String valueOf(int index)
 將數字index的內容用字符串表示
 String valueOf(long l)
 將長整數字l的內容用字符串表示
 String substring(int1,int2)
 取出字符串內第int1位置到int2的字符串

 
view plaincopy to clipboardprint?
import java.util.Collections;   
import java.util.Comparator;   
import java.util.LinkedList;   
import java.util.List;   
public class StringUsage {   
 // 幾個歐不太用的方法。   
 public static void main(String[] args) {   
  // 判斷字符串首/尾。   
  String contentS = "test String again. test ";   
  System.out.println(contentS);   
  System.out.println("contentS.startsWith(\"test\")\t"  
    + contentS.startsWith("test"));   
  System.out.println("contentS.endsWith(\"test\")\t"  
    + contentS.endsWith("test"));   
  // 忽略大小寫的字符串比較方法。   
  System.out   
    .println("contentS.compareToIgnoreCase(contentS.toUpperCase()))\t"  
      + contentS.compareToIgnoreCase(contentS.toUpperCase()));   
  // 不區分大小寫的字符串比較。   
  Comparator cmprStr = String.CASE_INSENSITIVE_ORDER;   
  List lstStr = new LinkedList();   
  // 準備數據。   
  lstStr.add("test");   
  lstStr.add("Test");   
  lstStr.add("tEst");   
  lstStr.add("rest");   
  lstStr.add("sest");   
     
  // 不區分大小寫的排序。   
  Collections.sort(lstStr, cmprStr);   
  System.out.println(lstStr);   
  // 區分大小寫的排序。   
  Collections.sort(lstStr);   
  System.out.println(lstStr);   
  System.out.println("\ntest String.valueOf()");   
     
  // 用 valueOf 處理 null 對象的字符串轉換。   
  try {   
   String ss = null;   
   System.out.println(ss);   
   System.out.println(String.valueOf(null)); // 比較奇怪的地方   
  } catch (RuntimeException e1) {   
      e1.printStackTrace();   
  }   
     
  BigDecimal db = null;   
  try {   
   System.out.println(((BigDecimal)db).toString());   
  } catch (Exception e) {   
   e.printStackTrace();   
  }   
  try {   
   System.out.println(String.valueOf(db));   
  } catch (Exception e) {   
   e.printStackTrace();   
  }   
  db = new BigDecimal("100.00");   
  try {   
   System.out.println(((BigDecimal)db).toString());   
  } catch (Exception e) {   
   e.printStackTrace();   
  }   
 }   
}  
 
五、SCJP題目
 
String a="Hello World!";
String b="Hello World!";
a=b?  a和b是否相等? 爲什麼?

String a=new String("Hello World!");
String b="Hello World!";
a=b?  a和b是否相等 ? 爲什麼?
 
解釋:
1. 首先String不屬於8種基本數據類型,String是一個對象。
因爲對象的默認值是null,所以String的默認值也是null;但它又是一種特殊的對象,有其它對象沒有的一些特性。  

2. new String()和new String(“”)都是申明一個新的空字符串,是空串不是null;

3. String str="kvill";
    String str=new String (“kvill”);的區別:  
在這裏,我們不談堆,也不談棧,只先簡單引入常量池這個簡單的概念。  
常量池(constant pool)指的是在編譯期被確定,並被保存在已編譯的.class文件中的
一些數據。它包括了關於類、方法、接口等中的常量,也包括字符串常量。  
看例1:  
String s0="kvill";  
String s1="kvill";  
String s2="kv" + "ill";  
System.out.println( s0==s1 );  
System.out.println( s0==s2 );  
結果爲:  
true  
true  
首先,我們要知道Java會確保一個字符串常量只有一個拷貝。  
因爲例子中的s0和s1中的”kvill”都是字符串常量,它們在編譯期就被確定了,所以
s0==s1爲true;而”kv”和”ill”也都是字符串常量,當一個字符串由多個字符串常量連
接而成時,它自己肯定也是字符串常量,所以s2也同樣在編譯期就被解析爲一個字符串常量,所以s2也是常量池中”kvill”的一個引用。所以我們得出s0==s1==s2;  

用new String() 創建的字符串不是常量,不能在編譯期就確定,所以new String() 
創建的字符串不放入常量池中,它們有自己的地址空間。  

看例2:  
String s0="kvill";  
String s1=new String("kvill");  
String s2="kv"+ new String("ill");  
System.out.println( s0==s1 );  
System.out.println( s0==s2 );  
System.out.println( s1==s2 );  
結果爲:  
false  
false  
false  
例2中s0還是常量池中”kvill”的應用,s1因爲無法在編譯期確定,所以是運行時創
建的新對象”kvill”的引用,s2因爲有後半部分new String(“ill”)所以也無法在編譯
期確定,所以也是一個新創建對象”kvill”的應用;明白了這些也就知道爲何得出此結果了。  

4. String.intern():  
再補充介紹一點:存在於.class文件中的常量池,在運行期被JVM裝載,並且可以擴充。String的intern()方法就是擴充常量池的一個方法;當一個String實例str調用intern()方法時,Java查找常量池中是否有相同Unicode的字符串常量,如果有,則返回其的引用,如果沒有,則在常量池中增加一個Unicode等於str的字符串並返回它的引用;看例3就清楚了。  

例3:  
String s0= "kvill";  
String s1=new String("kvill");  
String s2=new String("kvill");  
System.out.println( s0==s1 );  
System.out.println( “**********” );  
s1.intern(); 
s2=s2.intern(); //把常量池中"kvill"的引用賦給s2  
System.out.println( s0==s1);  
System.out.println( s0==s1.intern() );  
System.out.println( s0==s2 );  
結果爲:  
false  
**********  
false //雖然執行了s1.intern(),但它的返回值沒有賦給s1  
true //說明s1.intern()返回的是常量池中”kvill”的引用  
true 
 
最後我再破除一個錯誤的理解:  
有人說,“使用String.intern()方法則可以將一個String類的保存到一個全局Strin
g表中,如果具有相同值的Unicode字符串已經在這個表中,那麼該方法返回表中已有字符串的地址,如果在表中沒有相同值的字符串,則將自己的地址註冊到表中“如果我把他說的這個全局的String表理解爲常量池的話,他的最後一句話,“如果在表中沒有相同值的字符串,則將自己的地址註冊到表中”是錯的:  

看例4:  
String s1=new String("kvill");  
String s2=s1.intern();  
System.out.println( s1==s1.intern() );  
System.out.println( s1+" "+s2 );  
System.out.println( s2==s1.intern() );  
結果:  
false  
kvill kvill  
true  
在這個類中我們沒有聲名一個"kvill"常量,所以s1.intern()同new String("kvill")是不同的,當我們調用s1.intern()後就在常量池中新添加了一個"kvill"常量,原來的不在常量池中的"kvill"仍然存在,也就不是“將自己的地址註冊到常量池中”了。  
s1==s1.intern()爲false說明原來的“kvill”仍然存在;  
s2現在爲常量池中“kvill”的地址,所以有s2==s1.intern()爲true。  

5. 關於equals()和==:  

這個對於String簡單來說就是比較兩字符串的Unicode序列是否相當,如果相等返回true;而==是比較兩字符串的地址是否相同,也就是是否是同一個字符串的引用。  

6. 關於String是不可變的  

這一說又要說很多,大家只要知道String的實例一旦生成就不會再改變了,比如說:
String str=”kv”+”ill”+” “+”ans”;  
就是有4個字符串常量,首先”kv”和”ill”生成了”kvill”存在內存中,然後”kvill”又和” “ 生成 ”kvill “存在內存中,最後又和生成了”kvill ans”;並把這個字符串的地址賦給了str,就是因爲String的“不可變”產生了很多臨時變量,這也就是爲什麼建議用StringBuffer的原因了,因爲StringBuffer是可改變的





構造方法: 
String() 
          初始化一個新創建的 String 對象,它表示一個空字符序列。 
String(byte[] bytes) 
          構造一個新的 String,方法是使用平臺的默認字符集解碼字節的指定數組。 
String(byte[] bytes, int offset, int length) 
          構造一個新的 String,方法是使用指定的字符集解碼字節的指定子數組。 
String(byte[] bytes, int offset, int length, String charsetName) 
          構造一個新的 String,方法是使用指定的字符集解碼字節的指定子數組。 
String(byte[] bytes, String charsetName) 
          構造一個新的 String,方法是使用指定的字符集解碼指定的字節數組。 
String(char[] value) 
          分配一個新的 String,它表示當前字符數組參數中包含的字符序列。 
String(char[] value, int offset, int count) 
          分配一個新的 String,它包含來自該字符數組參數的一個子數組的字符。 
String(int[] codePoints, int offset, int count) 
          分配一個新的 String,它包含該 Unicode 代碼點數組參數的一個子數組的字符。 
String(String original) 
          初始化一個新創建的 String 對象,表示一個與該參數相同的字符序列;換句話說,新創建的字符串是該參數字符串的一個副本。 
String(StringBuffer buffer) 
          分配一個新的字符串,它包含當前包含在字符串緩衝區參數中的字符序列。 
String(StringBuilder builder) 
          分配一個新的字符串,它包含當前包含在字符串生成器參數中的字符序列 
方法總結: 
char charAt(int index) 
          返回指定索引處的 char 值。 
int codePointAt(int index) 
          返回指定索引處的字符(Unicode 代碼點)。 
int codePointBefore(int index) 
          返回指定索引之前的字符(Unicode 代碼點)。 
int codePointCount(int beginIndex, int endIndex) 
          返回此 String 的指定文本範圍中的 Unicode 代碼點數。 
int compareTo(String anotherString) 
          按字典順序比較兩個字符串。 
int compareToIgnoreCase(String str) 
          不考慮大小寫,按字典順序比較兩個字符串。 
String concat(String str) 
          將指定字符串聯到此字符串的結尾。 
boolean contains(CharSequence s) 
          當且僅當此字符串包含 char 值的指定序列時,才返回 true。 
boolean contentEquals(CharSequence cs) 
          當且僅當此 String 表示與指定序列相同的 char 值時,才返回 true。 
boolean contentEquals(StringBuffer sb) 
          當且僅當此 String 表示與指定的 StringBuffer 相同的字符序列時,才返回 true。 
static String copyValueOf(char[] data) 
          返回指定數組中表示該字符序列的字符串。 
static String copyValueOf(char[] data, int offset, int count) 
          返回指定數組中表示該字符序列的字符串。 
boolean endsWith(String suffix) 
          測試此字符串是否以指定的後綴結束。 
boolean equals(Object anObject) 
          比較此字符串與指定的對象。 
boolean equalsIgnoreCase(String anotherString) 
          將此 String 與另一個 String 進行比較,不考慮大小寫。 
static String format(Locale l, String format, Object... args) 
          使用指定的語言環境、格式字符串和參數返回一個格式化字符串。 
static String format(String format, Object... args) 
          使用指定的格式字符串和參數返回一個格式化字符串。 
byte[] getBytes() 
          使用平臺默認的字符集將此 String 解碼爲字節序列,並將結果存儲到一個新的字節數組中。  
byte[] getBytes(String charsetName) 
          使用指定的字符集將此 String 解碼爲字節序列,並將結果存儲到一個新的字節數組中。 
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) 
          將字符從此字符串複製到目標字符數組。 
int hashCode() 
          返回此字符串的哈希碼。 
int indexOf(int ch) 
          返回指定字符在此字符串中第一次出現處的索引。 
int indexOf(int ch, int fromIndex) 
          從指定的索引開始搜索,返回在此字符串中第一次出現指定字符處的索引。 
int indexOf(String str) 
          返回第一次出現的指定子字符串在此字符串中的索引。 
int indexOf(String str, int fromIndex) 
          從指定的索引處開始,返回第一次出現的指定子字符串在此字符串中的索引。 
String intern() 
          返回字符串對象的規範化表示形式。 
int lastIndexOf(int ch) 
          返回最後一次出現的指定字符在此字符串中的索引。 
int lastIndexOf(int ch, int fromIndex) 
          從指定的索引處開始進行後向搜索,返回最後一次出現的指定字符在此字符串中的索引。 
int lastIndexOf(String str) 
          返回在此字符串中最右邊出現的指定子字符串的索引。 
int lastIndexOf(String str, int fromIndex) 
          從指定的索引處開始向後搜索,返回在此字符串中最後一次出現的指定子字符串的索引。 
int length() 
          返回此字符串的長度。 
boolean matches(String regex) 
          通知此字符串是否匹配給定的正則表達式。 
int offsetByCodePoints(int index, int codePointOffset) 
          返回此 String 中從給定的 index 處偏移 codePointOffset 個代碼點的索引。 
boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) 
          測試兩個字符串區域是否相等。 
boolean regionMatches(int toffset, String other, int ooffset, int len) 
          測試兩個字符串區域是否相等。 
String replace(char oldChar, char newChar) 
          返回一個新的字符串,它是通過用 newChar 替換此字符串中出現的所有 oldChar 而生成的。 
String replace(CharSequence target, CharSequence replacement) 
          使用指定的字面值替換序列替換此字符串匹配字面值目標序列的每個子字符串。 
String replaceAll(String regex, String replacement) 
          使用給定的 replacement 字符串替換此字符串匹配給定的正則表達式的每個子字符串。 
String replaceFirst(String regex, String replacement) 
          使用給定的 replacement 字符串替換此字符串匹配給定的正則表達式的第一個子字符串。 
String[] split(String regex) 
          根據給定的正則表達式的匹配來拆分此字符串。 
String[] split(String regex, int limit) 
          根據匹配給定的正則表達式來拆分此字符串。 
boolean startsWith(String PRefix) 
          測試此字符串是否以指定的前綴開始。 
boolean startsWith(String prefix, int toffset) 
          測試此字符串是否以指定前綴開始,該前綴以指定索引開始。 
CharSequence subSequence(int beginIndex, int endIndex) 
          返回一個新的字符序列,它是此序列的一個子序列。 
String substring(int beginIndex) 
          返回一個新的字符串,它是此字符串的一個子字符串。 
String substring(int beginIndex, int endIndex) 
          返回一個新字符串,它是此字符串的一個子字符串。 
char[] toCharArray() 
          將此字符串轉換爲一個新的字符數組。 
String toLowerCase() 
          使用默認語言環境的規則將此 String 中的所有字符都轉換爲小寫。 
String toLowerCase(Locale locale) 
          使用給定 Locale 的規則將此 String 中的所有字符都轉換爲小寫。 
String toString() 
          返回此對象本身(它已經是一個字符串!)。 
String toUpperCase() 
          使用默認語言環境的規則將此 String 中的所有字符都轉換爲大寫。 
String toUpperCase(Locale locale) 
          使用給定的 Locale 規則將此 String 中的所有字符都轉換爲大寫。 
String trim() 
          返回字符串的副本,忽略前導空白和尾部空白。 
static String valueOf(boolean b) 
          返回 boolean 參數的字符串表示形式。 
static String valueOf(char c) 
          返回 char 參數的字符串表示形式。 
static String valueOf(char[] data) 
          返回 char 數組參數的字符串表示形式。 
static String valueOf(char[] data, int offset, int count) 
          返回 char 數組參數的特定子數組的字符串表示形式。 
static String valueOf(double d) 
          返回 double 參數的字符串表示形式。 
static String valueOf(float f) 
          返回 float 參數的字符串表示形式。 
static String valueOf(int i) 
          返回 int 參數的字符串表示形式。 
static String valueOf(long l) 
          返回 long 參數的字符串表示形式。 
static String valueOf(Object obj) 
          返回 Object 參數的字符串表示形式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章