1. 程式人生 > >String類詳解

String類詳解

1.String class初步認知:不可變性
JDK中 String類中定義的方法,不會去改變字串引用中的資料值,最終會建立、返回新的字串物件引用。
2.編譯器如何實現兩個字串的連線操作
不同於想象,compiler會利用可變字串類StringBuilder的append方法,實現字串的拼接,完成後在呼叫toString()。
3.String類方法總結
length() 對於陣列來說,求長度用length,這裡的長度是方法,而對於陣列型別來說是成員變數
constructor:可過載型別為StringBuilder、String、char arrays、StringBuffer
charAt(int pos) 返回的是給定pos的字元char


toCharArray()返回的是字串陣列char[]
getchars(int start,int end,char [] dst, int dstbegin)得到字元陣列 char[]
equals()/equalsIgnoreCase() 比較兩個字串內容
contentEquals() 比較字元序列是否相同,與上面的函式不同在引數上,這裡的引數是CharSequence or StringBuffer
compareTo()比較兩個字串的大小 -1 0 正數 區分大小寫
contains() 過載後,引數型別豐富,判斷是否包含charsquence(StringBuilder、StringBuffer)
startsWith() /endsWith()引數只能是String
,過載後可多一個offset ,引數字串是否為帶匹配字串的字首(字尾)字串
indexOf() 過載後引數型別可以為:單個字元、字串(String)、起始位置,獲取給定字元/子字串的索引值
substring(int start,int end) 返回的給定位置上的子字串 end取不到
concat() 引數是String 返回一個新拼接後的String
replace() 過載後的引數可以為兩個char,兩個字串,返回的是新的字串
toUpperCase() toLowerCase() 返回新的字串
trim()返回去空格後的新字串
valueOf() 靜態方法 String.valueOf()返回的是任何物件的字串表達
4.靜態方法String.format()
返回格式化的String類物件,該方法呼叫Fomatter()實現格式化。
類似的我們有System.out.format() 直接將格式化資料輸出到控制檯。
談談Formatter類:
構造方法的引數是輸出流物件:可以是PrintStream、OutputStream、File。
該引數表明將格式化的資料輸出到哪裡去。
Formatter中的format():
引數指定格式化的資料樣子及資料來源,資料樣子可由資料出現的位置、資料的型別、資料表現形式共同決定
可用的資料型別有哪些呢?
s–字串
c–字元
d–decimal整數
x—hex整數
f --float
h–hash code
如何指定資料的表現形式呢?
寬度(最小長度)
精確性(字元創型別來說最大可顯示的長度、float資料來說小數點後可表達的位數,預設為6位)
%(-)寬度.精確度 (-)改變對齊方式:預設右對齊,-為左對齊,對齊方式僅僅存在有設定了寬度後相應的資料顯示在寬度的左邊還是右邊,沒有設定寬度,不存在對齊設定

//使用Formatter類
public class tryFormat {
	Formatter formatter;

	public tryFormat(Formatter formatter) { //為其傳入輸出流物件
		// TODO Auto-generated constructor stub
		this.formatter=formatter;
		
	}
	
	public void getTitle() {
		formatter.format("%-10s %5s %6s\n", "Name","Id","Price");
		formatter.format("%-10s %5s %6s\n", "----","--","-----");//為了達到長度補空格 第一個引數採用左對齊,剩餘部分右對齊 
	}
	public void getInfo(String name,int id,float price) {//呼叫format函式,設定輸出格式
		formatter.format("%10.10s %5d %6.2f\n", name,id,price);//字串最多顯示10位  小數最多顯示2位
	}
	public static void main(String[] args) {
	
		tryFormat tFormat=new tryFormat(new Formatter(System.out));//傳入輸出流引數後,可將format 函式的資料顯示在該輸出流中
		tFormat.getTitle();
		PrintStream printStream=new PrintStream(System.out);
		tryFormat tFormat2=new tryFormat(new Formatter(printStream));
		tFormat2.getInfo("potato is so deliocious ", 1, 10.36985f);
		tFormat.getInfo("tomato great", 2, 10.1f);
	}

}

5.正則表示式
String、StringBuffer、StringTokenizer類中提供了簡單的正則表示式功能,同時Java.util.regex包中提供了類Pattern和類Matcher可以實現完整的正則表示式功能。
先從簡單的String、Stringbuffer自帶的正則表示式功能講起:
三個方法支援正則表示式的查詢及處理:
match(“regex”)
spilt(“regex”) 以匹配到的字串切割目標字串,匹配到的子字串不出現在切割目標字串的結果中
replace(“regex”,“新的字串”)

建立正則表示式(regex):
一些特殊的表達即可表示character classes:
. any character
[abc] ==(a | b|c)==a or b or c
[^abc] 除了abc之外的任意一個字元
[a-zA-Z] a-z or A-Z中的一個字元
\s space |tab |newline
\d 0-9
\D 非0-9
\w [a-zA-Z_0-9]
boundary :
^ $
匹配次數:

  • 不曾匹配到 、匹配多次
  • +匹配到一次或者多次
  • ? 不曾匹配到、匹配一次
    匹配方法:
    greedy(預設、最長匹配)、獨佔、reluctant(最短匹配)

如何使用Matcher和Pattern類?

Pattern類中靜態方法:
Pattern.compile(String型別的正則表示式規則),生成pattern
Pattern.compile(正則表示式,int flag)
可選的flag(常用):
?m 可以按行匹配(由多行構成的字串)== Pattern.MULTILINE
?i 忽略大小寫==Pattern.CASE_INSENSITIVE
非靜態方法:
matcher(待檢測字串),使得pattern去匹配待檢測的字串,返回Matcher物件
spilt(待檢測字串),得到的是字串陣列(以在目標字串中匹配到的子串來切割檢測字串生成的字串陣列)

Matcher類的非靜態方法:
find()類似iterator,搜尋目標字串中是否還存在pattern ,目標字串的index自動改變以繼續查詢
find(i) i指定了目標字串的index,從指定的index查詢pattern(與上一個函式相比,指定了目標字串的index)
lookingat()pattern是否出現在目標字串的開始
matches()pattern是否完全等於目標字串(從頭到尾)
start()當前pattern匹配目標字串時得到的子串在目標字串的start index
end()當前pattern匹配目標字串時得到的子串在目標字串的end index+1
reset() 重新置入待檢測的字串 ,對待檢測的字串做相同的處理(matcher 或是 spilt)
appendReplacement(stringBuffer ,replacement)方法支援邊匹配邊替換:
StringBuffer儲存的是待檢測字串中匹配到的子串之前的字串,再將當前的replacement加到stringBuffer
appendTail(stringBuffer):
一旦使用了appendReplacement方法,還需要使用該方法,將待檢測的末尾未匹配的字串加到stringBuffer上
特別的是,replaceAll()和replaceFirst()是由字串物件呼叫,不需要特意生成pattern物件

關於groups的概念(由matcher物件呼叫):
在指定正則表示式時,通過括號形式指定了group,從左至右,第一個括號記為組1,依次往下,組0是指整個正則表示式。
相應的在匹配目標字串時,獲取到的目標字串的子串根據正則表示式也有組號
group(i) 獲取指定組號的字串
group()獲取整個字串
groupcount()獲取包含的組數

matcher+find方法簡單應用
package stringdemo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TestPatternAndMatcher {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("input text is\n"+ args[0]);
		for(String arg:args){
			System.out.println(" pattern is :"+arg);
			Pattern pattern=Pattern.compile(arg);
			Matcher matcher=pattern.matcher(args[0]);
			while(matcher.find()){
				System.out.println(matcher.group()+" start index is "+matcher.start());
			}
		}
	}
	

}

spilt方法簡單應用
public class TestPatternAndMatcher {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("input text is\n"+ args[0]);
		for(String arg:args){
			System.out.println(" pattern is :"+arg);
			Pattern pattern=Pattern.compile(arg);
			System.out.println(Arrays.toString(pattern.split(args[0])));
		}
	}
	

}

appendReplacement()和appendTail()應用
public class TestPatternAndMatcher {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("input text is\n"+ args[0]);
		for(String arg:args){
			System.out.println(" pattern is :"+arg);
			Pattern pattern=Pattern.compile(arg);
			Matcher matcher=pattern.matcher(args[0]);
			StringBuffer stringBuffer=new StringBuffer();
			while(matcher.find()){
				//System.out.println(matcher.group()+" start index is "+matcher.start());
			matcher.appendReplacement(stringBuffer, "ABC");
			
			}
			matcher.appendTail(stringBuffer);
			System.out.println(stringBuffer);
			//System.out.println(Arrays.toString(pattern.split(args[0])));
			
			
		}
	}
	

}

測試reset方法  是Matcher類的方法
public class TestPatternAndMatcher {
	public static void main(String[] args) {
		System.out.println("input text is: "+args[0]);
		Pattern pattern=Pattern.compile(args[1]);
		Matcher matcher=pattern.matcher(args[0]);
		while(matcher.find()){
			System.out.println(matcher.group());
		}
		matcher.reset("abc");
		//依舊是matcher方式匹配待匹配字串,改變了待檢測的字串
		while(matcher.find()){
			System.out.println(matcher.group());
		}
	}
}

6.Scanner類(總感覺Scanner還有好多東西)
在next()方法中,類似於spilt方法,將字串分割為陣列,預設以空格分割字串,封裝了tokenize、parsing操作,無需自己再去切分字串。
Scanner 構造方法的引數可以是String、InputStream、File、or something readable
預設的分割方式是空格,也可以設定pattern來分割字串,通過hasnext()和next()取出,使用useDelimiter(regex)
類似於match方法的字串匹配,不同的地方在於把可讀序列封裝為Scanner類了,使用方法改變:
Scanner物件封裝輸入資料,String表示pattern模式,進行匹配Scanner.next(pattern),scanner.match()返回匹配結果物件MatchResult

//scanner的usedelimiter()、next()、hasnext()  設定分隔符,得到切分結果
public class TestScanner {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String string="aa.bb.cc.dd ";
		Scanner scanner=new Scanner(string);
		String pattern="\\.";
		scanner.useDelimiter(pattern);
		while(scanner.hasNext())
			System.out.println(scanner.next());
	
		
	}

}

//在封裝的Scanner上去匹配某一個pattern,hasNext(),Next()方法實現匹配pattern,match方法得到匹配結果。
public class TestScanner {

public static void main(String[] args) {
	// TODO Auto-generated method stub
	String string="aa bb ccdd ";
	Scanner scanner=new Scanner(string);
String  pattern ="\\w+";
while(scanner.hasNext(pattern))
{
	scanner.next(pattern);
	MatchResult matchResult=scanner.match();
	System.out.println(matchResult.group());
}	
}

}
//利用scanner 不用自己擷取感興趣的資料,直接利用封裝的方法
public class Scanner2 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println(“please input your name”);
String in=scanner.nextLine();
System.out.println(“input your favorite age and number”);
int age=scanner.nextInt();
int number=scanner.nextInt();
//System.out.println("age is “+age+”, number is "+number);
System.out.format(“your age is %d, favorite number is %d”, age,number);
}
}