Apache Commons Lang 2.4 代码分析之StringUtils
变量
public static final String EMPTY = "";表示空字符串
public static final int INDEX_NOT_FOUND = -1;表示下表没有找到
private static final int PAD_LIMIT = 8192;重复一个字符串的最大次数
======================
一组判断函数
isEmpty方法判断参数字符串是否为空,如果字符串本身为空或长度为0,则返回真。
isNotEmpty方法判断参数字符串是否不为空,对上一个方法的结果取反。
isBlank方法判断参数字符串是否没有内容。如果字符串为空或长度为0,则返回真;否则,利用Character.isWhitespace方法测试每一个字符是否为空格,一旦有一个不是,则返回假,否则返回真。
isNotBlank方法判断参数字符串是否不是没有内容。对上一个方法的结果取反。
======================
trim相关
trim方法返回参数字符串去掉前后空格的结果,使用string本身的trim方法,只是在之前测验字符串是否为空。(实际上优化了string本身的trim方法)
trimToNull方法先去空格,然后利用isEmpty方法判断是否为空,空则返回null,否则返回处理后的结果。
trimToEmpty方法,如果参数字符串为null,则返回"",否则去空格后返回。
=======================
strip相关
strip方法和trim方法类似,不同的是,后者只可以去空格,而前者可以去掉任意名为stripChars的字符集合,如果该字符串(字符集合)为空,则两个方法是相同的。
stripStart方法在字符串str的前面去掉stripChars代表的字符集合,执行如下操作:
stripEnd方法在字符串str的后面去掉stripChars代表的字符集合,方法同stripStart,只不过游标从后向前移动。
strip方法,如果不提供stripChars,则设为Null。如果字符串为空,则返回该字符串,否则分别执行stripStart和stripEnd方法,并返回结果。
stripToNull方法,同trimToNull方法。
stripToEmpty方法,同trimToEmpty方法。
stripAll方法,参数为字符串数组,利用strip方法处理一组字符串,返回的也是数组,但非参数数组(new了一个新的)。
=====================
equals相关
equals方法比较两个字符串,使用其中一个的equals方法,只不过之前对两个字符串进行判空。如果两个字符串均为空,则返回真;如果第一个为空,第二个不为空,则返回假;如果第一个不为空,则利用第一个参数的equals方法获得结果。
equalsIgnoreCase方法不考虑大小写的比较字符串,方法和equals方法类似。
======================
indexOf相关
该组方法返回字符串中的某个字符串从左侧数第一次出现的位置。查找字符串可以是string或char,另外可以带一个参数,表示开始查找的位置。该组方法核心都是使用String对象的indexOf方法,不过在之前做一些空的判断(统一返回-1)。
ordinalIndexOf
该方法查找第ordinal个匹配的字符串(传统的indexOf都是查找第一个)。思路是用两个计数器记录找到的字符串位置和当前是第几个,然后循环查找字符串,当第二个计数器和ordinal相等时,返回第一个计数器的值。
lastIndexOf相关
该组方法返回字符串中的某个字符串从右侧数最后一次出现的位置。查找字符串可以是string或char,另外可以带一个参数,表示开始查找的位置。该组方法核心都是使用String对象的lastIndexOf方法,不过在之前做一些空的判断(统一返回-1)。
indexOfAny相关
该方法在字符串中查找一组字符,返回遇到的任意一个字符即可。这组字符可以作为char数组或String的形式传入。通过遍历当前字符串,如果字符和数组中的字符一致,则返回当前位置,否则返回-1。
indexOfAnyBut相关
该方法在字符串中查找一组字符,返回首先遇到的任意一个不在该组字符的位置即可。该方法可以看做是indexOfAny的反向方法。这组字符可以作为char数组或String的形式传入。处理和indexOfAny类似,只不过在遍历字符串时,如果遇到相同的字符,则直接在字符串中找下一个字符,直到找到第一个完全不在字符数组中的字符所在的位置。
indexOfAny和lastIndexOfAny
该方法返回被测字符串中,任意匹配字符串数组的位置,last表示从后向前匹配。处理方法是遍历字符串数组,然后依次在被查字符串中查找位置。同时由于字符串和字符不同,所以要记录当前找到的位置,如果下次找到的位置更靠左,则更新这个位置。这样就能做到在字符串数组中,找最先遇到的字符串的位置。last的遍历顺序相反。
===========================
contains相关
查找参数字符串是否在给定的字符串中,参数可以是char或string。如果给定字符串为空或参数字符串为空,则返回假,利用indexOf的结果是否为-1确定返回值。
containsIgnoreCase
该方法查找参数字符串是否在给定的字符串中,不考虑大小写。原理是把字符串全部转换为大写后,利用contains方法判断。
containsAny相关
该方法在字符串中确定是否存在一组字符中的任意一个。这组字符可以作为char数组或String的形式传入。通过遍历当前字符串,如果字符和数组中的字符一致,则返回真,否则返回假。
containsOnly相关
测试字符串是否只包含字符数组中的那些字符。如果被测字符串和字符数组有一个为空,则为假。如果被测字符串长度为0,则为真。如果字符数组长度为0,则为假。否则利用indexOfAnyBut方法得到位置,如果该位置为-1(详见indexOfAnyBut的意义),则返回真,否则返回假。
containsNone相关
测试字符串是否任意一个字符数组中的字符。遍历字符串,如果任意一个字符与字符数组中的字符相同,则返回真,否则返回假。
==============================
substring相关
和String对象的substring方法类似,只是在之前对字符串进行校验,如果为null,则返回null。
另外对start进行校验:如果start小于0,则加长度(即把负数作为从右侧开始计数);如果还小于0,则设为0;如果大于长度,则返回""。
如果存在end,进行校验:如果都小于0,则加长度;如果end大于长度,则等于长度;如果start大于end,返回"";如果start或end还小于0,则置为0。
substringBefore相关
substringBefore方法返回被测字符串中,在参数字符串之前的部分。如果被测字符串为空或参数字符串为null,则返回被测字符串;如果参数字符串长度为0,则返回"";在被测字符串中取参数字符串的位置,如果不存在,则返回被测字符串,否则返回该位置之前的子字符串。
substringBeforeLast方法与上一个方法类似,只是在查找参数字符串时,使用String的lastIndexOf方法,即结束位置在最后一个匹配参数字符串的位置。
substringAfter相关
substringAfter方法与substringBefore类似,只不过取当前位置向后的那部分子字符串。
substringAfterLast与substringBeforeLast类似,只不过取当前位置向后的那部分子字符串。
substringBetween相关
substringBetween方法在被测字符串中截取前后字符串之间的子字符串(前后字符串可以为一个字符串)。首先确定前字符串的位置,如果不存在则返回null。然后确定后字符串的位置,如果不存在则返回null。最后返回两个位置之间的子字符串。
substringsBetween方法的不同之处在于返回所有前后字符串之间的子字符串,形成一个数组。注意这里只返回前后字符串中间的内容,而后前之间的内容不是返回的结果。在循环遍历中,依次查找前后字符串,然后把中间的内容加到一个数组中。直到指针超过最后一个后字符串。
left/right/mid相关
left方法获取字符串从左向右的n个长度的子字符串。利用String的substring方法获取,其中start为0,len为n。之前有一些判断,如果n小于0,则返回"";如果n大于长度,则返回当前字符串。
right方法获取字符串从右向左的n个长度的子字符串。利用String的substring方法获取,其中start取长度减n。之前判断同left方法。
mid方法取字符串中部从p开始的n个长度的子字符串。利用String的substring方法获取,其中start为p,len为p加n。之前有一些判断,如果n小于0或p大于长度,则返回"";如果p小于0,则置为0;如果n+p大于长度,则返回从p开始的所有子字符串。
===========================
split相关
私有方法splitWorker是一个核心方法,用于拆分字符串,其中字符c表示分隔符,另外布尔变量b表示c在首尾的不同处理方式。为真,则在首位留一个""的字符串。但是在中间是没有作用的。该方法执行如下操作:
私有方法splitWorker也是一个核心方法,用于拆分字符串,其与上一个方法的不同之处在于其分隔符用字符串表示一组字符,且增加一个max变量,表示输出的字符串数组的最大长度。另外注意该方法的b如果为真,会在首尾及中间起作用,且如果分隔符字符串长度大于1,则数组中的""会更多(根据分隔符字符的数量)。该方法执行如下操作:
split方法族用于分割字符串,根据参数不同有以下几种。
如果参数只有待分割的字符串,则默认使用" "来分隔字符串。结果数组长度不限(用-1表示),且b为假。
如果参数还包含分割字符,则使用第一个splitWorker来分隔,且b为假。
如果参数用字符串表示分割字符,则使用第二个splitWorker来分隔。结果数组长度不限(用-1表示),且b为假。
如果参数还包含max,则使用第二个splitWorker来分隔,且b为假。
splitPreserveAllTokens相关
保留分隔符空位的方式分割字符串,同split方法的参数相同,只是在所有调用splitWorker方法(不管第一个还是第二个)时,b均为真。
私有方法splitByWholeSeparatorWor
该方法依然要注意max的值在数组中的控制。
splitByWholeSeparator相关
利用splitByWholeSeparatorWor
splitByWholeSeparatorPre
利用splitByWholeSeparatorWor
splitByCharacterType相关
私有方法splitByCharacterType利用字符串中的每个字符的类型进行划分,并返回字符串数组。参数包含一个是否保留camel-class类型,即第一个字符是大写,第二个字符为小写的类型。执行如下操作:
splitByCharacterType方法的参数为被测字符串,利用同名私有方法获取结果,其中布尔参数为假。
splitByCharacterTypeCame
================================
join相关
join方法类似于split的反函数,有几种不同参数的同名方法,如下。
参数1为要连接的对象数组,参数2为连接字符,参数3,4为需要连接的对象数组的上限下限值。执行如下操作:
参数1为要连接的对象数组,参数2为连接字符串,参数3,4为需要连接的对象数组的上限下限值。执行如下操作:
参数1为一个迭代器,参数2为连接字符。执行如下操作:
参数1为一个迭代器,参数2为连接字符串。执行如下操作:
除了以上核心方法,还提供了几个同名方法:
参数为Collection对象,利用该对象的iterator方法调用join方法。
参数如果不包含上下限值,则默认为0和对象数组的长度。
参数如果不包含连接字符,则默认为null。
=====================
deleteWhitespace方法去掉字符串中的所有空格。方法是把字符串中所有非空格的内容拷贝到一个数组中,并记录拷贝了多少个字符,最后从数组中输出字符串。
remove相关
removeStart方法删除字符串中位于开头的被删字符串。判断字符串是否以被删字符串开头,如果是真,则取从被删字符串长度之后的子字符串。
removeStartIgnoreCase方法删除字符串中位于开头的被删字符串,不考虑字符的大小写。首先利用startsWithIgnoreCase方法判断是否满足删除条件,如果是,则取从被删字符串长度之后的子字符串。
removeEnd方法删除字符串中位于结尾的被删字符串。判断字符串是否以被删字符串结尾,如果是真,则取0到整个字符串长度减去被删字符串长度的子字符串。
removeEndIgnoreCase方法删除字符串中位于结尾的被删字符串,不考虑字符的大小写。首先利用endsWithIgnoreCase方法判断是否满足删除条件,如果是真,则取0到整个字符串长度减去被删字符串长度的子字符串。
remove方法从字符串中删除字符,把字符串转换成字符数组,遍历该数组,如果当前字符等于要删除的字符,则在数组中屏蔽该字符。
remove方法从字符串中删除字符串,利用replace方法实现。
=======================
replace相关
核心的replace方法提供四个参数,分别是原字符串s,需要替换的字符串p,替换的字符串t和最大替换数量c。执行如下操作:
除了核心方法,提供一个同名方法,只是最大替换数量默认为-1(即不受限制)。
replaceOne方法在调用核心方法时,最大替换数量默认为1(即只替换一个)。
核心的replaceEach方法是在一个字符串中替换一组字符串,但是由于提高效率,采用了全新的算法。该方法提供5个参数,分别是原字符串s,需要替换的字符串数组pp,替换的字符串数组tt,是否重复,执行n次替换等。执行如下操作:
同名的replaceEach方法对原字符串进行一次的替换工作,其中是否重复设为否,n为0。
replaceEachRepeatedly方法对原字符串进行循环的替换工作。在调用核心方法前,n的值定义为被替换字符串数组的长度。
replaceChars相关
如果替换和被替换的参数直接就是字符,则采用String的对应方法,只是如果原字符串为null,则返回null。
如果替换和被替换的参数是用字符串表示的字符数组,则执行如下操作:
=========================
overlay
overlay方法把原字符串中的一部分替换为指定字符串。参数除了原字符串和替换字符串外,还包括替换的起止点。
===============================
chomp相关
chomp方法从原字符串的最后去掉参数中指定的字符串。
如果参数包含这两个字符串,则如果原字符串确实以指定字符串结尾,则返回0到指定字符串之前的内容。其他情况返回原字符串。
如果参数只包含原字符串,则定义为去掉字符串最后的“新行”标志。执行如下操作:
chop方法删除最后一个字符,如果是\n,且倒数第二个是\r,则删除2个。
============================
repeat
repeat方法用于重复原字符串n次后输出。执行如下操作:
======================
pad相关
padding方法把一个字符赋值N个以后,形成字符串返回,如果N为负数,则抛出IndexOutOfBoundsExceptio
rightPad方法是通过在原字符串右侧补充若干个字符,使总长度达到参数要求的N长度。其执行如下操作:
另一个rightPad方法和上面的功能相同,只不过填充的部分不是字符而是字符串。其执行如下操作:
还有一个只提供原字符串和N长度的rightPad方法,其利用' '作为填充字符,调用第一个rightPad方法。
leftPad方法和rightPad方法类似,只是填充的部分在原字符串的左侧。其方法构成也相同,只是在连接的时候,总是使用填充字符(串)形成的字符串去连接原字符串。
center相关
center方法也属于pad相关的方法,不同的是其填充字符(串)在原字符串的两侧。其先调用leftPad方法,在其左侧填充整个差值的一半的字符,然后再调用rightPad方法插入后面的字符。
===================
length方法是在string的对应方法前做null的判断,如果是Null,则返回0。
===================
case conversion相关
upperCase方法调用String的同名方法,只是在之前验证字符串是否为null,如果是,返回null。
lowerCase方法调用String的同名方法,只是在之前验证字符串是否为null,如果是,返回null。
capitalize方法实现字符串的首字母大写。如果原字符串为空,则返回原字符串,否则用一个StringBuffer,先利用Character.toTitleCase写入原字符串的第一个字符,再写入原字符串从1开始的字符串,并返回。
uncapitalize方法去掉字符串的首字母大写,原理同上,只是使用Character.toLowerCase方法写入原字符串的第一个字符。
swapCase方法对原字符串进行大小写的转换。如果原字符串为空,则返回原字符串,否则用一个StringBuffer,遍历原字符串,如果遇到大写或首字符,则转换为小写并写入sb,如果遇到小写则转换为大写并写入sb,最后返回sb.toString方法。
==================
countMatches方法计算原字符串中被比较的字符串出现的次数。如果两者都为空,则返回0,否则遍历原字符串,如果用indexOf方法发现一个被比较字符串,则计数器加1,并重新设定指针。最后返回计数器。
==================
Character Test相关
isAlpha方法判断字符串是否只包含字母,如果字符串是null,则返回假。遍历字符串,如果利用Character.isLetter方法判断的每个字符都是真,则返回真(如果字符串为"",则会返回真),否则返回假。
isAlphaSpace方法在上一个方法中进行扩展,如果字符不是字母而是空格,也返回真。
isAlphanumeric方法判断字符串是否为字母和数字的组合,在遍历的时候,使用Character.isLetterOrDigit方法进行判断。
isAlphanumericSpace方法在上一个方法中进行扩展,如果字符不是字母或数字而是空格,也返回真。
isAsciiPrintable方法判断字符串是否为可打印的ASCII码,在遍历的时候,使用CharUtils.isAsciiPrintable方法进行判断。
isNumeric方法判断字符串是否为数字,在遍历的时候,使用Character.isDigit方法进行判断。
isNumericSpace方法在上一个方法中进行扩展,如果字符不是数字而是空格,也返回真。
isWhitespace方法判断字符串是否为空白,注意此处使用Character.isWhitespace方法进行判断,和前面使用''来认定space还是有些不同。
=====================
default相关
defaultString方法提供两种方法,如果只有原字符串,则在原字符串为null时返回"",否则用替换字符串作为原字符串为null时的返回值。
defaultIfEmpty方法是用isEmpty方法检测原字符串,如果为真,则返回替换字符串。
=====================
reverse相关
reverse方法把字符串进行反转操作,如果字符串为null,则返回null。否则,把其装入到一个StringBuffer中,利用sb的reverse来做反转。
reverseDelimited方法是把原字符串进行分割后各自反转,然后在连接起来。首先利用split方法分割成字符串数组,然后利用ArrayUtils的reverse方法进行反转。然后利用join方法进行连接。
=====================
abbreviate相关
abbreviate方法对字符串进行缩减,被省略的部分用...代替。参数包括原字符串,左侧被省略后开始的位移和返回字符串的最大长度。执行如下操作:
另一个abbreviate方法是位移缺省为0。
========================
difference相关
difference方法比较两个字符串,并返回字符串2中和字符串1不同的部分。执行如下操作:
indexOfDifference方法返回两个字符串从哪个位置开始不同。执行如下操作:
另外一个indexOfDifference方法返回一组字符串中开始不同的位置。执行如下操作:
getCommonPrefix方法取得一组字符串中一样的前缀。执行如下操作:
==========================
getLevenshteinDistance方法是为了计算两个字符串需要完全一致,较短的那个字符串需要修改的字符的数量。这个算法的实现比较复杂,这里就不记录了。
==========================
startWith/endWith相关
startsWith方法确定字符串是否以某前缀作为开始,参数中还包括是否考虑忽略大小写。执行如下操作:
另外两个方法只是在忽略大小写上的设置不同。
endWith方法和startWith基本相同