Commons-lang記錄 – JAVA編程語言程序開發技術文章

Commons-lang記錄:
一個最常用的工具,作為jdk的補充,有必要看一下源碼~~


篇章1——package:lang.*
Lang.*下有很多Utils類,提供瞭若幹static方法供調用,涵蓋瞭字符串操作、字符操作、JVM交互操作、歸類、異常和位域校驗等等。


首先看看字符串處理類StringUtils
全部的靜態方法,StringUtils繼承自Object。屬於null safe操作。何謂null safe,就是遇到是null的string對象,也會quietly的把它處理掉,而不會有NullPointerException異常,如果有這個異常,那麼就是該類的bug瞭~~


看看StringUtils的各種方法對比吧


比較一下isEmpty和isBlank這兩個方法。isEmpty在判斷” “這樣的字符串時返回的是false,而isBlank返回的是true。這就明顯瞭吧,empty隻對null和””有效,而blank對” ”也有效~~


Clean方法和trim方法都封裝瞭String的trim方法,唯一的不同是clean將null處理為””,而trim將null處理為null。


以Strip開頭的一系列方法基本可以看做trim方法的擴展,但是更強大的是可以處理前導和後續的各種stripChars,不局限於空白符瞭。


Equal系列的方法加入瞭null的判斷,如果都是null那麼也返回true。


IndexOf與String的indexOf類似,加入瞭null的判斷而已,且多瞭一個ordinalIndexOf方法,可以找到第n個字符串出現的位置。還有一個indexOfIgnoreCase可以不考慮大小寫的判斷位置匹配。實際代碼是調用瞭string的regionMatches方法,隻不過在ignorecase參數上選擇瞭true。


Contains的實現是一樣的,隻是加入瞭null的判斷。剩下的indexOfAny和containsAny方法都很不錯,完成瞭集合的匹配~~都包含一個字符數組的參數,可以檢測字符串中是否包含字符數組中的任意個元素,算法沒有特殊的地方,復雜度O(MN)吧~~相比較而言,contains系列的containsOnly和containsNone我倒是覺得更有用一些。


Substring系列的方法,除瞭substring封裝瞭string的substring完成瞭null safe的檢查外,還加入瞭left、right和mid方法。顧名思義,left可以得到最左邊的若幹個字符作為字串,其實就是調用瞭str.substring(0, len);而right同樣是調用瞭str.substring(str.length() – len);另外還有一些比如substringBefore和substringAfter之類的,用法類似。substringBetween可以找到兩個字串中間的子串。


Split是值得說道的一個改動,原本大量封裝string的方法,split是個例外,大傢知道,string的split方法用到的參數是一個正則式,雖然強大,但是有時候容易出錯。而且string並沒有提供簡化版本。StringUtils提供的split改變瞭這一狀況,開始使用完整的字符串作為參數,而不是regex。同時,對類似功能的jdk版本的StringTokenizer,在內部方法splitWorker中有段註釋:Direct code is quicker than StringTokenizer.也就是說,這個是更快的一個工具瞭~~


對於split的反向操作join,用到瞭一個lang.text包下的StrBuilder類。主要實現即將若幹個object數組一個個的append到buffer中。然後最後toString就好。


Delete和remove可以用來刪除string中的內容,比如deleteSpaces可以除去字符串中的所有空白字符(” “t”r”n”b”);remove更強大,可以removeStart(隻匹配開頭)和removeEnd(隻匹配結尾),當然remove可以刪掉字符串中的任意字串。


Replace,同理這裡的replace不像string中的一樣是基於正則的,用起來更簡單。而且有replaceOnce和replaceEach等各種用法。還有一個輔助的overlay方法,可以直接替換~~


Chomp和chop我覺得是比較雞肋的一個功能瞭,去除字符串的最後一個字符或者尾部串,這功能很必要麼?


Repeat將已有字符串復制n次。


Pad是一個很有意思的方法,可以將一個已有字符串擴展n個大小,並且填充特定的字符。比如StringUtils.rightPad(“bat”, 5, z) = “batzz”。Pad調用瞭string的concat方法。


Case conversion的操作就不用多講瞭,upper和lower都是一樣的。補充說的是,capitalize系列的方法真的很貼心。


補充一個容易讓人誤會的方法——countMatches,記錄一個字符串str中某串sub出現的次數。為什麼容易誤會,“aaaa”中有多少“aa”呢?用該方法得到的答案是2~~~大傢懂的


Is打頭的一系列方法都非常強大,可以判斷字符串是否符合某種格式,比如isAlpha判斷是否都是字母,isNumeric判斷是否都是數字等等等等。


Reverse這個功能出來後,最先想到的是當初筆試面試時候的一堆回文字符串翻轉之類的考試都要囧瞭。


Abbreviate方法我覺得是相當實用的一個方法封裝,我們在各種應用中都很常見的“一堆文字……”就是這個方法的最好應用。


Difference方法返回兩個字符串的不同處,可以說是返回第二個字符串的第一個不同的位置開始的子串。indexOfDifference返回不同處的位置。


getCommonPrefix這個方法也很好,可以找到一組字符串的公共前綴。當然隻是調用瞭indexOfDifference這個方法。


接著就是ArrayUtils瞭
ArrayUtils是一個對數組進行特殊處理的類。當然jdk中的Arrays是有一些功能的,Array也提供瞭一些動態訪問java數組的方法,這裡的ArrayUtils擴展提供瞭更多的功能。


第一個可以說的方法是toMap方法,該方法就是將一個二維數組轉換為一個HashMap。當然對輸入的參數要求比較嚴格,會拋出各種異常。NullToEmpty方法是一個防禦性編程方法的代表,將null的數組直接變為一個空(長度為0)的數組。Subarray方法提供瞭基於拷貝的子數組生成方法。Reverse方法提供瞭一個數組翻轉的算法實現。indexOf方法是一個查找指定對象的線性數組查找方法。還提供瞭一系列裝箱拆箱方法(toPrimitive和toObject),就是將Integer之類的對象類型變成int,反之亦然。addAll方法提供瞭基於數組拷貝的數組合並,就是將數組1和數組2合並為一個新的數組返回。當然,add方法雖然隻添加瞭一個元素,但是也是要數組拷貝的(數組的效率啊!!!)。同樣的原理,remove(刪除)方法也是基於數組拷貝的,以指定刪除元素為界,分別兩次拷貝它前後的子數組。


再來就是一些補充瞭
把一些看到的有意思的可能有用的接口方法提取出來。


RandomStringUtils類裡有一個random方法,可以產生一個固定長度的隨機字符串。用到瞭java.util.Random。其中的註釋中提到瞭對Unicode中沒法處理的surrogate的處理方法。如果不幸隨機到那個位置(D800-DBFF, DC00-DFFF),那麼算法中將進行count補充,即提供一次重新隨機的機會。


另外一個比較有趣的類是StopWatch,這是一個秒表類,通過start方法開始計時,通過split方法截斷每一次的分段計時,suspend方法可以暫停秒表,resume恢復計時。最後stop後可以通過getTime獲得總共計時。當然在split後的分段計時可以用getSplitTime獲取。技術實現上就是定義瞭幾個狀態,然後通過每次狀態的轉變和系統時間的差來表達計時效果。


參考資料:


http://commons.apache.org/lang/userguide.html


 

發佈留言