天天看點

String的split方法的使用1.引言2.split用法3.split源碼分析4.擴充

1.引言

split方法很常用,記得我入職公司的時候,第一道筆試題就是關于字元串的拆分拼裝等,這也足以說明,大公司對這些方法的重視程度.

其實我們平時一般用到的都是這些方法最簡單的用法,但如果你不了解他的實作原理,碰到某些特殊問題終究是會被卡住的,于是就産生了所謂的bug,而這也就是大神和菜鳥的差別之一吧.廣度是一方面,但真正看一個程式員是不是牛逼,重要的還是看他的深度,比如這個split的用法,如果你還停留在簡單的用法上,不妨看看後面,也看看你的深度,與君共勉!

2.split用法

先上一個例子:

1.最普通的用法
		String str1 = "aa,bb";
		String[] split1 = str1.split(",");
		System.out.println(split1.length);
		//這個結果是2,都知道的
2.比較普通的用法
		String str2 = "";
		String[] split2 = str2.split(",");
		System.out.println(split2.length);
		//這個結果是1,但部分人會認為這個的結果是0,
		//這個為什麼是1,我會在後面說
3.看起來比較奇怪的用法
		String str3 = ",";
		String[] split3 = str3.split(",");
		System.out.println(split3.length);
		//這個結果是0,但部分人會認為結果是1,部分人會認為結果是2.
		//這個又為什麼是0,我也會在後面說
           

3.split源碼分析

split方法準确的來說有兩個參數(String regex, int limit),隻不過平時我們用的,是split的一個重載方法(String regex),預設是把第二個參數設定為0,源碼如下:

public String[] split(String regex) {
        return split(regex, 0);
    }
    
    public String[] split(String regex, int limit) {
		具體實作...
	}
           

3.1.參數解釋—regex

1.如果表達式不比對輸入的任何内容,傳回的數組隻具有一個元素,即此字元串。(尤其注意空字元串這種情況,他也是一個字元串)

2.可以比對的情況下,每一個字元串都由另一個比對給定表達式的子字元串終止,或者由此字元串末尾終止(數組中的字元串按照他們在此字元串出現的順序排列)

3.2.參數解釋—limit

該參數用于控制模式比對使用的次數,可以影響到數組的長度

1.limit>0:

模式比對将被最多應用n-1次,數組的長度将不會大于n,數組的最後一項将包含所有超出最後比對的定界符的輸入。

2.limit<0:

模式比對将應用盡可能多的次數,而且數組的長度是任何長度。

3.lilmit=0:

模式比對将被應用盡可能多的次數,數組可以是任何長度,并且結尾空字元串将被丢棄。

3.3.不同limit值的情況下的split結果驗證

假設有字元串aa,bcd,eef,

3.3.1.limit=0,regex=","

尾部的逗号,直接被忽略,頭部的逗号不會忽略

String line = ",aa,bcd,eef,,,";
String[] split = line.split(",",0);
System.out.println(split.length);//4
           

3.3.2.limit=2,regex=","

總長度被限制成最大2個

String line = ",aa,bcd,eef,,,";
String[] split = line.split(",",2);
System.out.println(split.length);//2
           

3.3.3.limit=100,regex=","

總長度被限制成最大100個

但結果是7個,說明當limit大于0,并且遠大于應該有的長度時,頭部和尾部的逗号都沒有被忽略

String line = ",aa,bcd,eef,,,";
String[] split = line.split(",",100);
System.out.println(split.length);//7
           

3.3.4.limit=-1,regex=","

結果是7個,說明當limit小于0時,頭部和尾部的逗号都沒有被忽略

String line = ",aa,bcd,eef,,,";
String[] split = line.split(",",100);
System.out.println(split.length);//7
           

4.擴充

谷歌的guava包,也有對split的重寫,傳回的是list數組集合.

具體使用如下:

<dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>24.1-jre</version>
        </dependency>
           
String line = ",aa,bcd,eef,,,";
List<String> split2 = Splitter.on(",").splitToList(line);
System.out.println(split2.size());//7
           

根據結果,我們可以看到,谷歌的split預設是頭部和尾部的逗号都沒有被忽略,相當于java包下split的limit設定為-1

相比下,java包下split的limit預設不寫就是0,即頭部逗号沒有被忽略,而尾部逗号是被忽略的

一定要注意區分