尚籌網10使用者登入
不可變String
String物件是不可變的,在api文件中有明確說明,String類中每一個看起來會修改String值的方法,實際上都是建立了一個全新的物件。
public class Immutable { public static String upcase(String s ){ return s.toUpperCase(); } public static void main(String[] args) { String q = "howdy"; System.out.println(q); String qq = Immutable.upcase(q); System.out.println(qq); System.out.println(q); } }
String物件q是小寫,把q作為引數傳入upcase()轉換成大寫之後得到物件qq,此時q的值發生變化了嗎?沒有,它仍然是小寫的。即q當引數傳過去的只是它的引用的一個副本。其實,每當把String物件當作引數傳遞給方法的時候,傳的都是此物件的副本。
過載“+” 與 StringBuilder
因為String物件是不可變的,所以一個String物件可以加任意多的別名。但是不變性會帶來一定的效率問題。為String過載的"+"操作符就是一個例子。(String的"+","+="是Java中僅有的兩個過載過的操作符,且Java不允許程式設計師過載任何操作符)。
public class Concatenation {
public static void main(String[] args) {
String mango = "mango";
String s = "abc" + mango + "def" +47;
System.out.println(s);
}
}
上述程式碼可能是這樣工作的:
當adc和mango連線之後,建立一個物件,當abcmango和def連線後又建立一個物件,當abcmangodef和47連線後又建立一個物件。此方式會產生一大堆需要垃圾回收的中間物件。
而實際上編譯器是怎麼做的呢?
在這個例子中,編譯器建立了一個StringBuilder物件(雖然我們沒有使用StringBuilder物件,但編譯器卻自作主張的使用了,因為它高效),用以構造最終的String,併為每個字串呼叫一次StringBuildert的append()方法,總計四次。最後呼叫toString()生成結果,並存為s。
StringBuilder是一個可變的字元序列。它提供了豐富而全面的方法,包括insert(),repleace(),substring(),reverse().
public class StringBuilderTest {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
System.out.println(sb.append("abcdefghijk"));//末尾新增
System.out.println(sb.insert(11,"l"));//指定位置新增。
System.out.println(sb.replace(0,2,"xyz"));//替換指定位置字串
System.out.println(sb.substring(0,3));//字串擷取
System.out.println(sb.reverse());//字串反序
}
StringBuilder是Java SE5之後引入的,在這之前用的是StringBuffer。StringBuffer是執行緒安全的,因此開銷也會大些。
String上的操作
public class StringTest {
public static void main(String[] args) {
String s = new String("123456789");
System.out.println(s.length());//返回字串長度
System.out.println(s.charAt(0));//根據索引查詢索引位置的值(字串本質是字元陣列)
byte[] b = s.getBytes();//將字串轉換成位元組陣列
char[] c = new char[10];
/*
srcBegin -- 從字串中第srcBegin開始複製。
srcEnd -- 到字串中srcEnd結束(不含srcEnd)。
dst -- 將字串複製到此目標陣列。
dstBegin -- 目標陣列中的起始偏移量(比如目標陣列容量是10,偏移量設定為1的話,從第二個位置開始儲存)。
*/
s.getChars(6, 9, c, 5);//將字串選擇性的複製到字元陣列中。
for (int i = 0; i < c.length; i++)
{
System.out.println(c[i]);
}
char[] c1 = s.toCharArray();//將字串完全複製到字元陣列中
for(char element : c1)
{
System.out.println(element);
}
String s1 = "abcdefg";
String s2 = "ABCDEFG";
System.out.println(s1.equals(s2));//比較兩個物件內容是否相同(區分大小寫)
System.out.println(s1.equalsIgnoreCase(s2));//比較兩個物件內容是否相同(不區分大小寫)
System.out.println(s1.compareTo(s2));//按字典順序比較String的內容,如果此字串等於引數字串,則值0 ; 如果此字串按字典順序小於字串引數,則小於0 ; 如果此字串按字典順序大於字串引數,則值大於0 。
System.out.println(s1.contains("de"));//字串包含指定的char值序列時,才返回true。
System.out.println(s1.contentEquals("abcdefg"));//當引數與String物件完全一致時,才返回true。
String region1 = "123abc456";
String region2 = "456abc123";
/*
ignoreCase -- 如果為 true,則比較字元時忽略大小寫。
toffset -- 此字串中子區域的起始偏移量。
other -- 字串引數。
ooffset -- 字串引數中子區域的起始偏移量。
len -- 要比較的字元數。
*/
System.out.println(region1.regionMatches(true, 3, region2, 3, 2));
String str = " 12345 7789 ";
System.out.println(str.length()); //刪除所有前導和尾隨空格
System.out.println(str.trim().length());
}
}
格式化輸出
Java SE5引入的format方法可用於PrintStream或PrintWriter物件,其中也包括System.out物件。format()模仿自C的printf()。
public class SimpleFormat {
public static void main(String[] args) {
int x = 5;
double y = 5.156;
//old way
System.out.println("x=" + x + " " + "y=" + y);
//new way
System.out.format("x=%d y=%f\n",x,y);
//or
System.out.printf("x=%d y=%f",x,y);
}
}
在Java中所有新的格式化功能都由Formatter類來處理。當你建立一個Formatter物件的時候,你需要向其構造器傳入一些資訊,告訴它最終結果將向哪裡輸出。
public class Turtle {
private String name;
private Formatter f;
public Turtle(String name, Formatter f) {
this.name = name;
this.f = f;
}
public void move(int x, int y){
f.format("%s The Turtle is at (%d,%d)\n",name,x,y);
}
public static void main(String[] args) {
PrintStream outAlias = System.out;
Turtle tom = new Turtle("Tom", new Formatter(System.out));
Turtle terry = new Turtle("Terry", new Formatter(outAlias));
tom.move(5, 7);
terry.move(4, 6);
}
}
正則表示式
正則表示式是一種強大的文字處理工具,它的作用:1.驗證字串是否符合指定特徵。比如驗證是否是合法的郵箱地址。2.用來查詢字串,從一個長的文字中查詢符合指定特徵的字串。3.用來替換。
基礎
正則表示式就是以某種方式來描述字串,例如abcj-5sada,你要找一個數字,它可能有一個負號在前面。你可以這樣表示-?。
描述一個整數:在正則表示式中用\d表示一位數字,Java中對反斜線\有不同的處理。在其他語言中\表示我想在正則表示式中插入一個反斜線。而在Java中\表示我要插入一個正則表示式的反斜線。所以你想在Java中用正則表示式表示一位數字需要這樣表示:\d.你想在正則表示式中插入反斜線需要這樣表示:\\。不過換行和製表還是用單斜線\n\t.
表示一個或多個:使用+,例如表示一個負號後面跟著多位數字可以這樣表示:-?\d+
String類自帶了一個非常有用的正則表示式工具——split(),其功能是:將字串從正則表示式匹配的地方切開。
Pattern和Matcher
一般來說,比起功能有限的String類,我們更願意構造功能強大的正則表示式物件。用Pattern.compile()來編譯你的正則表示式即可。它會根據你給的正則表示式生成一個Pattern物件。接下來把你想要檢索的字串傳入Pattern物件的matcher().此方法會生成一個Matcher物件。它有很多功能可用。
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");