長(zhǎng)字符串切分,取其中元素封裝或者將封裝信息組合成長(zhǎng)字符串都是常規(guī)操作,但是這種長(zhǎng)字符串往往是不可控的,如一個(gè)長(zhǎng)字符串就是由一個(gè)元素組成,或者存在空字符串的元素,看似這并沒有什么問題,但是使用不同工具類的split
方法進(jìn)行切分結(jié)果是完全不同的。不知道你是否遇到這樣的坑,下面一起來看看。
創(chuàng)新互聯(lián)建站專注于斗門企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,成都商城網(wǎng)站開發(fā)。斗門網(wǎng)站建設(shè)公司,為斗門等地區(qū)提供建站服務(wù)。全流程按需開發(fā)網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)建站專業(yè)和態(tài)度為您提供的服務(wù)
直接使用String本身自帶的split
方法,看對(duì)不同字符串的切分結(jié)果。
沒有分隔符的字符串
//str = "1"
public static void split2(String str) {
String[] splits = str.split(",");
for (String split : splits) {
System.out.println("->" + split);
}
System.out.println("數(shù)組長(zhǎng)度:" + splits.length);
}
切分后結(jié)果是單個(gè)元素["1"]
,數(shù)組長(zhǎng)度是1。
有分隔符,分隔符切分后沒有空字符串出現(xiàn)
//str = "1,2"
//代碼同上……
切分后結(jié)果是["1","2"]
,數(shù)組長(zhǎng)度是2。(假設(shè)分隔符是n個(gè),分割后的元素個(gè)數(shù)是n+1個(gè))
有分隔符,分隔符切分后有空字符串出現(xiàn)
//str = "1,,2"
//代碼同上……
切分后結(jié)果是["1","","2"]
,數(shù)組長(zhǎng)度是3。(假設(shè)分隔符是n個(gè),分割后的元素個(gè)數(shù)是n+1個(gè))
最終總結(jié)不管分隔符有多少個(gè),最終切分的結(jié)果都是n+1個(gè)元素。也是正常業(yè)務(wù)邏輯所需要的。但是這里有一個(gè)問題,如果傳入的字符串是null
的時(shí)候會(huì)報(bào)NullPointException
異常,需要另外加一層非空判斷。
具體全限定類名是org.apache.commons.lang3.StringUtils
,這個(gè)可以說是最常用一個(gè)字符串的工具類。如判斷非null
、非空字符串或者非空格,用isNotBlank
方法,使用集合元素組裝字符串,用join
方法等等?,F(xiàn)在來看一下split
方法在不同的情況下是如何實(shí)現(xiàn)。
沒有分隔符的字符串
//str = "1"
public static void split1(String str) {
String[] splits = org.apache.commons.lang3.StringUtils.split(str, ",");
for (String split : splits) {
System.out.println("->" + split);
}
System.out.println("數(shù)組長(zhǎng)度:" + splits.length);
}
切分后的結(jié)果是單個(gè)元素["1"]
,數(shù)組長(zhǎng)度為1。
有分隔符,分隔符切分后沒有空字符串出現(xiàn)
//str = "1,2"
//代碼同上……
切分后的結(jié)果是兩個(gè)元素["1","2"]
,數(shù)組長(zhǎng)度為2。
有分隔符,分隔符切分后有空字符串出現(xiàn)
//str = "1,,2"
//代碼同上……
切分后的結(jié)果和上一種情況結(jié)果是一樣的,也是兩個(gè)元素["1","2"]
,數(shù)組長(zhǎng)度為2。
從這里就可以看的出來問題的所在,當(dāng)出現(xiàn)空字符串的時(shí)候,會(huì)自動(dòng)將空字符串丟棄,只保留非空字符串。但是這里還是需要注意的是如果是空格,也會(huì)形成一個(gè)元素。比如現(xiàn)在str輸入的是"1, ,2"
,兩個(gè)分隔符間有一個(gè)空格,此時(shí)就會(huì)切分成三個(gè)元素。
全限定類名org.springframework.util.StringUtils
,這個(gè)StringUtils也經(jīng)常被用到,因?yàn)樵谳斎隨tringUtils的時(shí)候,IDEA自動(dòng)提示,往往它就是在第一位。那它和上面兩種在split
方法上有什么不同呢?
沒有分隔符的字符串
//str = "1"
public static void split3(String str) {
String[] splits = org.springframework.util.StringUtils.split(str, ",");
for (String split : splits) {
System.out.println("->" + split);
}
System.out.println("數(shù)組長(zhǎng)度:" + splits.length);
}
這個(gè)時(shí)候?qū)Σ黄?,?huì)報(bào)NullPointerException
異常,也就是這個(gè)split
方法必須要有分隔符的存在。
有分隔符,分隔符切分后沒有空字符串出現(xiàn)
//str = "1,2"
//代碼同上……
切分后的結(jié)果是兩個(gè)元素["1","2"]
,數(shù)組長(zhǎng)度為2。
有分隔符,分隔符切分后有空字符串出現(xiàn)
//str = "1,,2"
//代碼同上……
切分后的結(jié)果是兩個(gè)元素["1",",2"]
,數(shù)組長(zhǎng)度為2??吹竭@里可能你會(huì)認(rèn)為我這個(gè)數(shù)組格式寫錯(cuò)了,但是實(shí)際上第二個(gè)元素的確是這樣的,確定無疑。
這個(gè)split
方法還是很坑的,它會(huì)從字符串中找分隔符是否存在,如果不存在直接報(bào)錯(cuò),如果存在,不管有多少個(gè)分隔符,都是以第一個(gè)分隔符做切分,最終形成兩個(gè)元素。
三個(gè)split
方法三種不同的切分邏輯,到底在什么時(shí)候用那種方式切分就很講究了,因?yàn)樵陂_發(fā)過程中因?yàn)檫@個(gè)切分出過很多莫名其妙的BUG。我就遇到過兩次。
org.apache.commons.lang3.StringUtils
來切分字符串,字符串內(nèi)有空字符串存在,導(dǎo)致切割后的元素個(gè)數(shù)和實(shí)際個(gè)數(shù)不同,準(zhǔn)確的來說少了元素,結(jié)果代碼中在向另一個(gè)字符串占位符中填充數(shù)據(jù)的時(shí)候,總是出現(xiàn)錯(cuò)位的現(xiàn)象。(如本來應(yīng)該放在占位符3位置上的字符串出現(xiàn)為空字符串,在切分的時(shí)候,3位置的元素實(shí)際被拋棄,4位置的元素放在了3的位置)org.apache.commons.lang3.StringUtils
來切分字符串,測(cè)試一直都是很正常,但是測(cè)試一段時(shí)間后,發(fā)現(xiàn)報(bào)NullPointException
,排查后才發(fā)現(xiàn),引入的StringUtils被其他開發(fā)人員換成了org.springframework.util.StringUtils
導(dǎo)致的。因?yàn)檫@個(gè)字符串可能沒有分隔符。