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);返回結果是一個很奇怪的字符串[I@77a82f1;使用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" 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM