1. 程式人生 > >Apache Commons包 StringUtils工具類深入整理

Apache Commons包 StringUtils工具類深入整理

字串是在程式開發中最常見的,Apache Commons開源專案在org.apache.commons.lang3包下提供了StringUtils工具類,該類相當於是對jdk自帶的String類的增強,主要做了幾方面的處理: 1.核心設計理念就是對於null的進行內部處理,使用時不再需要進行繁瑣的null值判定,同時也避免丟擲空指標的異常 2.作為工具類,通過增加額外處理的方式,儘量避免丟擲異常,例如擷取字串,如指定長度超過了最大長度,不會丟擲異常 3.通過更多的過載方法,實現了忽略大小寫、增加控制範圍(左側、右側、中間)等常用操作 4.增加了批量功能,如批量判定、批量比對等(個人認為批量功能適用的場景會比較少) 5.通過對基本功能的綜合應用,增加可直接實現特定開發場景的功能方法   整個工具類經過多年不斷積累,非常龐大,官方按照功能,分了二十幾個大類,方法總數達到了200多個,但其實常用和實用的其實並不沒有那麼多,因此從使用的角度,進行了重新整理,以便更好地利用起來,轉換為開發生產力。   幾個概念先明確下: 1.null:String是引用型別而不是基本型別,所以取值可以為null 2.空串:即不包含任何元素的字串,表示為"" 3.空格:即" ",對應ascii碼是32 4.空白字元:是一組非可見的字元,對於文字處理來說,除了空格外,通常包括tab(\t)、回車(\r)、換行(\n)、垂直製表符(\v)、換頁符(\f),當然,windows系統常用的回車換行的組合(\r\n)也算在其中。    官方文件地址:http://commons.apache.org/proper/commons-lang/javadocs/api-3.8.1/index.html 以下是個人根據開發經驗,站在使用者角度,重新整理和歸類。
注: 1.以下整理方法排除掉了官方標記為過時的方法 2.涉及到正則表示式的方法,官方從StringUtils中移除,更換到了RegExUtils類中,不再在StringUtils中體現。      1 判斷與驗證 根據特定規則判斷,不改變字串自身 1.1判斷是否包含內容 提供了兩類方法,empty類和blank類,區別在對於前者只有為null或空串時,才返回true,而後者則會包含所有空白字元(空格、tab、換行、回車等)的判定,使用時需根據要實現的目的來選擇具體用哪一個。 兩大類方法完全類似,只列出empty類方法 簽名: public static boolean isEmpty(CharSequence cs) 說明: 只有為null或空串時,才返回true 示例: StringUtils.isEmpty(null); // true StringUtils.isEmpty("");   // true 擴充套件: //判定是否非空串 public static boolean isNotEmpty(CharSequence cs) //批量判斷,不定數量引數或陣列 public static boolean isAnyEmpty(CharSequence... css) public static boolean isAllEmpty(CharSequence... css) public static boolean isNoneEmpty(CharSequence... css)   1.2 比較字串  基本用法equals、equalsIgnoreCase、compareTo、compareToIgnoreCase,同jdk. 擴充套件點: 1)擴充套件equalsAny,可批量進行匹配判定,幾乎不會用到,建議使用集合的contains方法更自然。 2)通過compareTo過載函式,可以指定null物件的優先順序

1.3 檢驗字串
通過一系列實現好的方法,來快速返回是否符合特定規則
//判斷是否只包含unicode字元(注意:漢字也是unicode字元)
public static boolean isAlpha(CharSequence cs)
//判斷是否只包含unicode字元及空格
public static boolean isAlphaSpace(CharSequence cs)
//判斷是否只包含unicode字元及數字
public static boolean isAlphanumeric(CharSequence cs)
//判斷是否只包含unicode字元、數字及空格
public static boolean isAlphanumericSpace(CharSequence cs)
//判斷是否只包含數字及空格
public static boolean isNumericSpace(CharSequence cs)
//判斷是否只包含可列印的ascii碼字元(注意,空格不屬於範圍內)
public static boolean isAsciiPrintable(CharSequence cs)
//判斷是否為數字(注意:小數點和正負號,都會判定為false)
public static boolean isNumeric(CharSequence cs)
//判定是否只包括空白字元
public static boolean isWhitespace(CharSequence cs)
//判定是否全部為大寫
public static boolean isAllUpperCase(CharSequence cs)
//判定是否全部為小寫
public static boolean isAllLowerCase(CharSequence cs)
//判定是否混合大小寫(注意:包含其他字元,如空格,不影響結果判定)
public static boolean isMixedCase(CharSequence cs)

 

1.4 包含字串
contains,同jdk
public static boolean contains(CharSequence seq,int searchChar)
public static boolean contains(CharSequence seq,CharSequence searchSeq)
擴充套件:
//忽略大小寫
public static boolean containsIgnoreCase(CharSequence str,CharSequence searchStr)
//是否包含空白字元
public static boolean containsWhitespace(CharSequence seq)
//只包含指定字元
public static boolean containsOnly(CharSequence cs,char... searchChars)
public static boolean containsOnly(CharSequence cs,CharSequence searchChars)
//批量判斷包含任意一個
public static boolean containsAny(CharSequence cs,char... searchChars)
public static boolean containsAny(CharSequence cs,CharSequence searchChars)
//批量判斷不包含任何一個
public static boolean containsNone(CharSequence cs,char... searchChars)
public static boolean containsNone(CharSequence cs,CharSequence searchChars)

 

1.5 起止字元判定
//startWith
public static boolean startsWith(CharSequence str,CharSequence prefix)
public static boolean startsWithIgnoreCase(CharSequence str,CharSequence prefix)
public static boolean startsWithAny(CharSequence sequence,CharSequence... searchStrings)
//endWith
public static boolean endsWith(CharSequence str,CharSequence suffix)
public static boolean endsWithIgnoreCase(CharSequence str,CharSequence suffix)
public static boolean endsWithAny(CharSequence sequence,CharSequence... searchStrings)

2 處理字串

不改變字串實質內容,對首尾以及中間的空白字元進行處理 

2.1 移除空白字元 去除首尾的空白字元,提供了兩類方法,strip類和trim類, trim類與jdk差異不大,去除包含控制字元(ascii碼<=32)在內的控制字元(底層應用沒做過,有可能會用到控制字元吧),主要是增加了對null的處理。 strip類則做了很多增強,通過過載方法實現了很多其他功能,建議在開發中使用strip類。 注意:全形空格並不在處理範圍內。 簽名: public static String strip(String str) 擴充套件: //去除並轉化為null或empty public static String stripToNull(String str) public static String stripToEmpty(String str) //去除指定字串 public static String strip(String str,String stripChars) //控制去除範圍 public static String stripStart(String str,String stripChars) public static String stripEnd(String str,String stripChars)

//批量操作
public static String[] stripAll(String... strs)
public static String[] stripAll(String[] strs,String stripChars) 

相關方法: //對字串基本處理的複合應用,將字串中所有空白字元去除 public static String deleteWhitespace(String str) //去除首尾,但中間的空白字元,替換為單個空格 public static String normalizeSpace(String str) //去除聲調音標,官方舉例是將 'à' 轉換為'a',很生僻,基本不會用到,不確定漢語拼音的音標是否能處理 public static String stripAccents(String input)  

2.2 去除換行
去除結尾的一處換行符,包括三種情況 \r \n \r\n
public static String chomp(String str)
示例
StringUtils.chomp("\r") = ""
StringUtils.chomp("\n") = ""
StringUtils.chomp("\r\n") = ""
StringUtils.chomp("abc \r") = "abc "
StringUtils.chomp("abc\n") = "abc"
StringUtils.chomp("abc\r\n") = "abc"
StringUtils.chomp("abc\r\n\r\n") = "abc\r\n"
StringUtils.chomp("abc\n\r") = "abc\n"
StringUtils.chomp("abc\n\rabc") = "abc\n\rabc"

2.3 去除間隔符
去除末尾一個字元,常見使用場景是通過迴圈處理使用間隔符拼裝的字串,去除間隔符
注意:使用時需確保最後一位一定是間隔符,否則有可能破壞正常資料

public static String chop(String str)
示例:
StringUtils.chop("1,2,3,") = "1,2,3"
StringUtils.chop("a") = ""
StringUtils.chop("abc") = "ab"
StringUtils.chop("abc\nabc") = "abc\nab"

//此外,末尾的換行符也視為字元,如果結尾是\r\n,則一塊去除,建議使用專用的chomp,以免造成非預期的結果
StringUtils.chop("\r") = ""
StringUtils.chop("\n") = ""
StringUtils.chop("\r\n") = ""

2.4 去除非數字
去除所有非數字字元,將剩餘的數字字元拼接成字串
public static String getDigits(String str)
示例:
StringUtils.getDigits("abc") = ""
StringUtils.getDigits("1000$") = "1000"
StringUtils.getDigits("1123~45") = "112345"
StringUtils.getDigits("(541) 754-3010") = "5417543010"

   3.查詢字串   3.1查詢字串  indexOf與lastIndexOf,可搜尋字元、字串以及指定起始搜尋位置,同jdk。

public static int indexOf(CharSequence seq,CharSequence searchSeq)

public static int indexOf(CharSequence seq,CharSequence searchSeq,int startPos)

  擴充套件

//增加忽略大小寫控制
public static int indexOfIgnoreCase(CharSequence str,CharSequence searchStr)
//返回第n次匹配的所在的索引數。
public static int ordinalIndexOf(CharSequence str,CharSequence searchStr,int ordinal)
//同時查詢多個字元
public static int indexOfAny(CharSequence cs,char... searchChars)
//返回不在搜尋字元範圍內的第一個索引位置
public static int indexOfAnyBut(CharSequence cs,char... searchChars)

        4.編輯字串 字串的分割、合併、擷取、替換  4.1 分割字串 

jdk中的split使用正則表示式匹配,而字串分割最常用場景是如下這種根據間隔符分割
String str="he,ll,o";
String [] reuslt=str.split(",");
雖然split的方式也能實現效果,但是還有有點彆扭,而在StringUtils,就是通過字串匹配,而不是正則表示式
//不設定間隔符,預設使用空白字元分割
public static String[] split(String str)
//根據間隔符分割 
public static String[] splitByWholeSeparator(String str,String separator)
//限定返回,貪婪匹配
public static String[] splitByWholeSeparator(String str,String separator,int max),
示例:
StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 5) = ["ab", "cd", "ef"]
StringUtils.splitByWholeSeparator("ab-!-cd-!-ef", "-!-", 2) = ["ab", "cd-!-ef"]
//空白字元作為一個數組元素返回(其他方法預設去除空白字元元素)
public static String[] splitPreserveAllTokens(String str) 
示例:
StringUtils.splitPreserveAllTokens("abc def") = ["abc", "def"]
StringUtils.splitPreserveAllTokens("abc def") = ["abc", "", "def"]
StringUtils.splitPreserveAllTokens(" abc ") = ["", "abc", ""]
//特定場景,根據字元型別分割,同一類劃為一個數組元素,駝峰命名情況下,最後一個大寫字母歸屬後面元素而不是前面
public static String[] splitByCharacterTypeCamelCase(String str)
示例:
StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
StringUtils.splitByCharacterTypeCamelCase("ab de fg") = ["ab", " ", "de", " ", "fg"]
StringUtils.splitByCharacterTypeCamelCase("ab:cd:ef") = ["ab", ":", "cd", ":", "ef"]
StringUtils.splitByCharacterTypeCamelCase("number5") = ["number", "5"]
StringUtils.splitByCharacterTypeCamelCase("fooBar") = ["foo", "Bar"]
StringUtils.splitByCharacterTypeCamelCase("foo200Bar") = ["foo", "200", "Bar"]
StringUtils.splitByCharacterTypeCamelCase("ASFRules") = ["ASF", "Rules"]

   

4.2 合併字串
jdk使用concat方法,StringUtils使用join,這是一個泛型方法,建議實際使用過程中,還是隻對String使用,不要對數值型別進行合併,會導致程式碼可讀性降低
//預設合併,注意:自動去除空白字元或null元素
public static <T> String join(T... elements)
示例:
StringUtils.join(null) = null
StringUtils.join([]) = ""
StringUtils.join([null]) = ""
StringUtils.join(["a", "b", "c"]) = "abc"
StringUtils.join([null, "", "a"]) = "a"

//使用指定間隔符合並,注意:保留空白字元或null元素
public static String join(Object[] array,char separator)
示例:
StringUtils.join(["a", "b", "c"], ';') = "a;b;c"
StringUtils.join([null, "", "a"], ';') = ";;a"


//拼接數值
public static String join(long[] array,char separator)
public static String join(int[] array,char separator)
示例:
StringUtils.join([1, 2, 3], ';') = "1;2;3"
StringUtils.join([1, 2, 3], null) = "123"
(注意:實測與官網文件不符,StringUtils.join(new int[]{1, 2, 3}, null);返回結果是一個很奇怪的字串[[email protected];使用StringUtils.join(new Object[]{1, 2, 3}, null)),才會返回期望的“123”

相關方法: 
//joinWith,基本就是把陣列引數和間隔符的位置顛倒了一下,意義不大,建議棄用
StringUtils.joinWith(",", {"a", "b"}) = "a,b"

此外,還有大量過載函式,進一步指定起始元素和結束元素,實用性較低,不建議使用。

  4.3 擷取字串

相關方法有多個,substring和truncate基本用法同jdk,內部處理異常

public static String substring(String str,int start)
public static String substring(String str,int start,int end)

public static String truncate(String str,int maxWidth);
public static String truncate(String str,int offset,int maxWidth)

擴充套件:

//直接實現從左側、右側或中間擷取指定位數,實用性高
public static String left(String str,int len)
public static String right(String str,int len)
public static String mid(String str,int pos,int len) 

//直接實現特定規則,但總體來說適用場景不多
//擷取第一個指定字元前/後的字串返回
public static String substringBefore(String str,String separator)
public static String substringAfter(String str,String separator)
//擷取最後一個指定字元前/後的字串返回
public static String substringBeforeLast(String str,String separator)
public static String substringAfterLast(String str,String separator)
//擷取特定字串中間部分
public static String substringBetween(String str,String tag)
示例:StringUtils.substringBetween("tagabctag", "tag") = "abc"
//返回起止字串中間的字串,且只返回第一次匹配結果
public static String substringBetween(String str,String open,String close)
//返回起止字串中間的字串,返回所有匹配結果
public static String[] substringBetween(String str,String open,String close)

     

4.4 替換字串
jdk中使用replace,StringUtils使用同樣名字,預設替換掉所有匹配項,擴充套件實現了忽略大小寫、只替換一次、指定最大替換次數等
public static String replace(String text,String searchString,String replacement)
public static String replaceChars(String str,char searchChar,char replaceChar)
擴充套件:
//忽略大小寫
public static String replaceIgnoreCase(String text,String searchString,String replacement)
//只替換一次
public static String replaceOnce(String text,String searchString,String replacement)
public static String replaceOnceIgnoreCase(String text,String searchString,String replacement)
//最大替換次數
public static String replace(String text,String searchString,String replacement,int max)
示例:
StringUtils.replace("abaa", "a", "z", 0) = "abaa"
StringUtils.replace("abaa", "a", "z", 1) = "zbaa"
StringUtils.replace("abaa", "a", "z", 2) = "zbza"
StringUtils.replace("abaa", "a", "z", -1) = "zbzz"
注意:
max是替換次數,0代表不做替換,-1代表替換所有,從程式碼可讀性考慮,建議按照常規思維模式使用,別使用這些0或者-1比較變態的用法

//擴充套件批量,過於複雜,執行結果難以預期,不建議使用
public static String replaceEach(String text,String[] searchList,String[] replacementList)
public static String replaceEachRepeatedly(String text,String[] searchList,String[] replacementList)
public static String replaceChars(String str,String searchChars,String replaceChars)

   

4.5.移除字串
remove,移除字元
public static String remove(String str,char remove)
public static String remove(String str,String remove)
示例:
StringUtils.remove("queued", "ue") = "qd"
(注意,是第二個引數中所有字元,而不是匹配整個字串)

擴充套件:
//忽略大小寫
public static String removeIgnoreCase(String str,String remove)
//移除指定位置
public static String removeStart(String str,String remove)
public static String removeEnd(String str,String remove)
//指定位置且忽略大小寫
public static String removeStartIgnoreCase(String str,String remove)
public static String removeEndIgnoreCase(String str,String remove)

   4.6.覆蓋部分字串
public static String overlay(String str,String overlay,int start,int end)
典型應用場景,隱藏字串如證件號碼、地址或手機號碼中部分字元
示例::
StringUtils.overlay("13712345678","****",3,7)=“137****5678”
注意:實現時做了不少防止異常的處理,比如後面兩個引數為止可以調換,會自動判斷哪個數字小,哪個就是起始值,然後,如果是負數,則表示新增到開始,如果超出字串自身長度,新增到末尾,但這些奇特的用法儘量避免使用,否則程式碼可讀性會很差。  

4.7 生成字串
根據指定資訊產生字串
public static String repeat(String str,int repeat)
示例:
StringUtils.repeat("a", 3) = "aaa"
StringUtils.repeat("ab", 2) = "abab"
擴充套件:
//指定間隔符
public static String repeat(String str,String separator,int repeat)
示例
StringUtils.repeat("?", ", ", 3) = "?, ?, ?" 


4.8 字首和字尾
//追加字首,如只有兩個引數,則是無條件追加,超過兩個引數,是在不匹配prefixes任何情況下才追加
public static String prependIfMissing(String str,CharSequence prefix,CharSequence... prefixes)
public static String prependIfMissingIgnoreCase(String str,CharSequence prefix,CharSequence... prefixes)
/追加字尾,如只有兩個引數,則是無條件追加,超過兩個引數,是在不匹配suffixes任何情況下才追加
public static String appendIfMissing(String str,CharSequence suffix,CharSequence... suffixes)
public static String appendIfMissingIgnoreCase(String str,CharSequence suffix,CharSequence... suffixes)

//無條件同時增加字首和字尾
public static String wrap(String str,char wrapWith)
public static String wrap(String str,String wrapWith)
//有條件同時增加字首和字尾
public static String wrapIfMissing(String str,char wrapWith)
public static String wrapIfMissing(String str,String wrapWith)
//去除字首和字尾
public static String unwrap(String str,char wrapChar)
public static String unwrap(String str,String wrapToken)

5.字串轉換
字串內容意義不變,形式變化

5.1 大小寫轉換
轉換字串至大寫或小寫狀態 
//轉換大寫
public static String upperCase(String str)
public static String upperCase(String str,Locale locale)
//轉換小寫
public static String lowerCase(String str)
public static String lowerCase(String str,Locale locale)
//首字母大寫
public static String capitalize(String str)
//首字母小寫
public static String uncapitalize(String str)
//大小寫交換,即大寫變小寫,小寫變大寫
public static String swapCase(String str)

5.2 字串縮略
將字串縮減為指定寬度
public static String abbreviate(String str,int maxWidth)
注意,maxWidth必須>=4,否則拋異常
如果字元長度小於maxWidth,直接返回該字串,否則縮減效果為 substring(str, 0, max-3) + "..."

示例:
StringUtils.abbreviate("abcdefg", 4) = "a..."
擴充套件:
//可指定縮減字元的省略符號
public static String abbreviate(String str,String abbrevMarker,int maxWidth)
示例:
StringUtils.abbreviate("abcdefg", "..", 4) = "ab.."
StringUtils.abbreviate("abcdefg", "..", 3) = "a.." 
另有其他過載函式,可指定起始位置,實現..ab..效果,同樣過於複雜,會導致程式碼可讀性變差,不建議使用

 

5.3 補齊字串
自動補齊至指定寬度,可指定字元,如不指定,預設補空格,有三個,center、leftPad和rightPad
使用場景:
1)顯示時補充資料寬度一致使其對齊,更美觀
2)單據流水號,寬度固定,左側補0

public static String center(String str,int size)
public static String center(String str,int size,char padChar)
public static String center(String str,int size,String padStr)

public static String leftPad(String str,int size)
public static String leftPad(String str,int size,char padChar)
public static String leftPad(String str,int size,String padStr)

public static String rightPad(String str,int size)
public static String rightPad(String str,int size,char padChar)
public static String rightPad(String str,int size,String padStr) 

 

5.4 旋轉字串
//shift大於0則右旋,小於0則左旋
public static String rotate(String str,int shift)
示例:
StringUtils.rotate("abcdefg", 2) = "fgabcde"
StringUtils.rotate("abcdefg", -2) = "cdefgab"
//完全顛倒字串順序
public static String reverse(String str)
//顛倒字串順序,以間隔符為單位進行,單個元素內部不顛倒位置
public static String reverseDelimited(String str,char separatorChar) 
示例:
StringUtils.reverseDelimited("a.bc.d",'.')=“d.bc.a”

   

5.5 編碼轉換
//將位元組陣列轉換為指定編碼的字串
public static String toEncodedString(byte[] bytes,Charset charset)
應用場景:系統間互動時,字元編碼不一致,如對方傳遞的引數編碼為GB2312,我方編碼為UTF-8,可通過該方法進行轉換

//轉換unicode位碼
public static int[] toCodePoints(CharSequence str)

 

6 其他

難以歸類的一些功能性方法

6.1 取字串長度
public static int length(CharSequence cs)

6.2.計算匹配次數
public static int countMatches(CharSequence str,CharSequence sub)
public static int countMatches(CharSequence str,char ch)


6.3 預設值處理
//獲取預設字串,null及空格將會返回“”,其他情況返回原始字串
public static String defaultString(String str)
//獲取預設字串,第一個引數為null及空格將會返回第二個引數指定值,其他情況返回原始字串
public static String defaultString(String str,String defaultStr)
//其他處理,如果為空白或空,返回指定值
public static <T extends CharSequence> T defaultIfBlank(T str,T defaultStr)
public static <T extends CharSequence> T defaultIfEmpty(T str,T defaultStr)
//其他處理,返回陣列中第一個不為空白或不為空的元素
public static <T extends CharSequence> T firstNonBlank(T... values)
public static <T extends CharSequence> T firstNonEmpty(T... values) 


6.4.字串差異
//返回字串差異部分,實用性差,不建議使用
public static String difference(String str1,String str2)
//返回字串差異的索引位置
public static int indexOfDifference(CharSequence cs1,CharSequence cs2)
public static int indexOfDifference(CharSequence... css)

6.5 取字串相同字首
public static String getCommonPrefix(String... strs)
示例:
StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"