溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

字符串split操作到底有多少坑

發(fā)布時(shí)間:2020-07-19 04:29:44 來源:網(wǎng)絡(luò) 閱讀:765 作者:程序猿洞曉 欄目:軟件技術(shù)

微信公眾號(hào)

字符串split操作到底有多少坑
長字符串切分,取其中元素封裝或者將封裝信息組合成長字符串都是常規(guī)操作,但是這種長字符串往往是不可控的,如一個(gè)長字符串就是由一個(gè)元素組成,或者存在空字符串的元素,看似這并沒有什么問題,但是使用不同工具類的split方法進(jìn)行切分結(jié)果是完全不同的。不知道你是否遇到這樣的坑,下面一起來看看。

String類自帶的split方法

直接使用String本身自帶的split方法,看對不同字符串的切分結(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ù)組長度:" + splits.length);
    }

    切分后結(jié)果是單個(gè)元素["1"],數(shù)組長度是1。

  • 有分隔符,分隔符切分后沒有空字符串出現(xiàn)

    //str = "1,2"
    //代碼同上……

    切分后結(jié)果是["1","2"],數(shù)組長度是2。(假設(shè)分隔符是n個(gè),分割后的元素個(gè)數(shù)是n+1個(gè))

  • 有分隔符,分隔符切分后有空字符串出現(xiàn)

    //str = "1,,2"
    //代碼同上……

    切分后結(jié)果是["1","","2"],數(shù)組長度是3。(假設(shè)分隔符是n個(gè),分割后的元素個(gè)數(shù)是n+1個(gè))

最終總結(jié)不管分隔符有多少個(gè),最終切分的結(jié)果都是n+1個(gè)元素。也是正常業(yè)務(wù)邏輯所需要的。但是這里有一個(gè)問題,如果傳入的字符串是null的時(shí)候會(huì)報(bào)NullPointException異常,需要另外加一層非空判斷。

commons提供的StringUtils工具類

具體全限定類名是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ù)組長度:" + splits.length);
    }

    切分后的結(jié)果是單個(gè)元素["1"],數(shù)組長度為1。

  • 有分隔符,分隔符切分后沒有空字符串出現(xiàn)

    //str = "1,2"
    //代碼同上……

    切分后的結(jié)果是兩個(gè)元素["1","2"],數(shù)組長度為2。

  • 有分隔符,分隔符切分后有空字符串出現(xiàn)

    //str = "1,,2"
    //代碼同上……

    切分后的結(jié)果和上一種情況結(jié)果是一樣的,也是兩個(gè)元素["1","2"],數(shù)組長度為2。

從這里就可以看的出來問題的所在,當(dāng)出現(xiàn)空字符串的時(shí)候,會(huì)自動(dòng)將空字符串丟棄,只保留非空字符串。但是這里還是需要注意的是如果是空格,也會(huì)形成一個(gè)元素。比如現(xiàn)在str輸入的是"1, ,2",兩個(gè)分隔符間有一個(gè)空格,此時(shí)就會(huì)切分成三個(gè)元素。

Spring下util包提供的StringUtils工具類

全限定類名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ù)組長度:" + splits.length);
    }

    這個(gè)時(shí)候?qū)Σ黄穑瑫?huì)報(bào)NullPointerException異常,也就是這個(gè)split方法必須要有分隔符的存在。

  • 有分隔符,分隔符切分后沒有空字符串出現(xiàn)

    //str = "1,2"
    //代碼同上……

    切分后的結(jié)果是兩個(gè)元素["1","2"],數(shù)組長度為2。

  • 有分隔符,分隔符切分后有空字符串出現(xiàn)

    //str = "1,,2"
    //代碼同上……

    切分后的結(jié)果是兩個(gè)元素["1",",2"],數(shù)組長度為2。看到這里可能你會(huì)認(rèn)為我這個(gè)數(shù)組格式寫錯(cuò)了,但是實(shí)際上第二個(gè)元素的確是這樣的,確定無疑。

這個(gè)split方法還是很坑的,它會(huì)從字符串中找分隔符是否存在,如果不存在直接報(bào)錯(cuò),如果存在,不管有多少個(gè)分隔符,都是以第一個(gè)分隔符做切分,最終形成兩個(gè)元素。

總結(jié)

三個(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來切分字符串,測試一直都是很正常,但是測試一段時(shí)間后,發(fā)現(xiàn)報(bào)NullPointException,排查后才發(fā)現(xiàn),引入的StringUtils被其他開發(fā)人員換成了org.springframework.util.StringUtils導(dǎo)致的。因?yàn)檫@個(gè)字符串可能沒有分隔符。
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI