目录
  1. 1. StringUtils解析
    1. 1.1. 字符串判定
      1. 1.1.1. 空检查
      2. 1.1.2. 比较字符串
      3. 1.1.3. contains
      4. 1.1.4. 检验字符串
      5. 1.1.5. 起止字符判定
    2. 1.2. 查找字符串
    3. 1.3. 字符串转换
      1. 1.3.1. 大小写转换
      2. 1.3.2. 补齐字符串
      3. 1.3.3. 旋转字符串
      4. 1.3.4. 缩略字符串
      5. 1.3.5. 编码
    4. 1.4. 字符串处理
      1. 1.4.1. 移除空白
      2. 1.4.2. 去除换行
      3. 1.4.3. 去间隔符
      4. 1.4.4. 去除非数字
    5. 1.5. 编辑字符串
      1. 1.5.1. 分割字符串
      2. 1.5.2. 合并字符串
      3. 1.5.3. 截取字符串
      4. 1.5.4. 移除字符串
      5. 1.5.5. 替换字符串
      6. 1.5.6. 覆盖字符串
      7. 1.5.7. 生成字符串
      8. 1.5.8. 前缀和后缀
    6. 1.6. 其他
      1. 1.6.1. 计算匹配次数
      2. 1.6.2. 默认值处理
      3. 1.6.3. 字符串差异
      4. 1.6.4. 取字符串相同的前缀
StringUtils解析

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)也算在其中

以下是个人根据开发经验,站在使用者角度,重新整理和归类
StringUtils.png

字符串判定

空检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 检查字符序列是否为 空串还是null
boolean isEmpty(final CharSequence cs)

// 检查字符序列是否为 非空串还是not null
boolean isNotEmpty(final CharSequence cs)

// 批量检查任何字符序列是否为空("")或null
boolean isAnyEmpty(final CharSequence... css)

// 批量检查所有CharSequences是否为空("")或null
boolean isNoneEmpty(final CharSequence... css)

// 批量检查所有CharSequences是否为空("")或null
boolean isAllEmpty(final CharSequence... css)

// 检查CharSequence是否为空("")、null或空白字符(空格、tab、换行、回车等)
boolean isBlank(final CharSequence cs)

// 检查CharSequence是否 非 空("")、null或空白字符(空格、tab、换行、回车等)
boolean isNotBlank(final CharSequence cs)

// 批量检查任一CharSequence是否 为空("")、null或空白字符(空格、tab、换行、回车等)
boolean isAnyBlank(final CharSequence... css)

// 批量检查所有CharSequences是否为空("")或null或空白字符
boolean isNoneBlank(final CharSequence... css)

// 批量检查所有CharSequences是否为空("")或null或空白字符
boolean isAllBlank(final CharSequence... css)

比较字符串

基本用法equals、equalsIgnoreCase、compareTo、compareToIgnoreCase,同jdk
扩展点:

  1. 扩展equalsAny,可批量进行匹配判定,几乎不会用到,建议使用集合的contains方法更自然
  2. 通过compareTo重载函数,可以指定null对象的优先级
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    boolean equals(final CharSequence cs1, final CharSequence cs2)

    // 忽略大小写
    boolean equalsIgnoreCase(final CharSequence cs1, final CharSequence cs2)

    // 相等为0;str1小于str2则<0;str1大于str2则>0(此处认为null的值小于非null的值)
    int compare(final String str1, final String str2)

    // 比较字符串; nullIsLess:是否认为null的值小于非null的值
    int compare(final String str1, final String str2, final boolean nullIsLess)

    // 忽略大小写的比较
    int compareIgnoreCase(final String str1, final String str2)

    // 忽略大小写的比较; nullIsLess:是否认为null的值小于非null的值
    int compareIgnoreCase(final String str1, final String str2, final boolean nullIsLess)

    // string只要与后续的字符串任意字符数组匹配,即为true
    boolean equalsAny(final CharSequence string, final CharSequence... searchStrings)

    contains

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // 检查CharSequence是否包含搜索字符
    boolean contains(final CharSequence seq, final int searchChar)

    // 忽略大小写
    boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr)

    // 是否包含空白字符
    boolean containsWhitespace(final CharSequence seq)

    // 批量判断包含任意一个
    boolean containsAny(final CharSequence cs, final char... searchChars)

    // 只包含指定字符
    boolean containsOnly(final CharSequence cs, final char... valid)

    // 批量判断不包含任何一个
    boolean containsNone(final CharSequence cs, final char... searchChars)

    检验字符串

    通过一系列实现好的方法,来快速返回是否符合特定规则
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // 判断是否只包含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)

    // 判断是否只包含可打印的ascii码字符(注意:空格不属于范围内)
    public static boolean isAsciiPrintable(CharSequence cs)

    // 判断是否为数字(注意:小数点和正负号,都会判定为false)
    public static boolean isNumeric(CharSequence cs)

    // 判断是否只包含数字及空格
    public static boolean isNumericSpace(CharSequence cs)

    // 判定是否只包括空白字符
    public static boolean isWhitespace(CharSequence cs)

    // 判定是否全部为小写
    public static boolean isAllLowerCase(CharSequence cs)

    // 判定是否全部为大写
    public static boolean isAllUpperCase(CharSequence cs)

    //判定是否混合大小写(注意:包含其他字符,如空格,不影响结果判定)
    public static boolean isMixedCase(CharSequence cs)

    起止字符判定

    1
    2
    3
    4
    5
    6
    7
    8
    //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)

查找字符串

indexOf与lastIndexOf,可搜索字符、字符串以及指定起始搜索位置,同jdk

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 返回第一次出现指定字符的索引
int indexOf(final CharSequence seq, final int searchChar)

// 返回第一次出现指定字符的索引,从指定索引处开始搜索
int indexOf(final CharSequence seq, final int searchChar, final int startPos)

// 处理null的情况,查找CharSequence中的第一个索引
int indexOf(final CharSequence seq, final CharSequence searchSeq)

// 查找CharSequence中的第一个索引,以startPos为起始
int indexOf(final CharSequence seq, final CharSequence searchSeq, final int startPos)

// 返回第n次匹配的所在的索引数
int ordinalIndexOf(CharSequence str,CharSequence searchStr,int ordinal)

// 增加忽略大小写控制
int indexOfIgnoreCase(CharSequence str,CharSequence searchStr)

// 返回最后一次出现指定字符的索引
int lastIndexOf(final CharSequence seq, final int searchChar)

// 返回指定字符最后一次出现在索引,从指定索引开始向后搜索
int lastIndexOf(final CharSequence seq, final int searchChar, final int startPos)

// 同时查找多个字符
int indexOfAny(final CharSequence cs, final char... searchChars)

// 返回不在搜索字符范围内的第一个索引位置
int indexOfAnyBut(final CharSequence cs, final char... searchChars)

字符串转换

字符串内容意义不变,形式变化

大小写转换

转换字符串至大写或小写状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 转换大写
public static String upperCase(String str)

// 转换小写
public static String lowerCase(String str)

// 首字母大写
public static String capitalize(String str)

// 首字母小写
public static String uncapitalize(String str)

// 大小写交换,即大写变小写,小写变大写
public static String swapCase(String str)

补齐字符串

自动补齐至指定宽度,可指定字符,如不指定默认补空格,有三个,center、leftPad和rightPad
使用场景:

  1. 显示时补充数据宽度一致使其对齐,更美观
  2. 单据流水号,宽度固定,左侧补0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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)

    旋转字符串

    1
    2
    3
    4
    5
    6
    7
    8
    // shift大于0则右旋,小于0则左旋
    public static String rotate(String str,int shift)

    // 完全颠倒字符串顺序
    public static String reverse(String str)

    // 颠倒字符串顺序,以间隔符为单位进行,单个元素内部不颠倒位置
    public static String reverseDelimited(String str,char separatorChar)

    缩略字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 将字符串缩减为指定宽度
    public static String abbreviate(String str,int maxWidth)

    注意:maxWidth必须>=4,否则抛异常
    如果字符长度小于maxWidth,直接返回该字符串,否则缩减效果为 substring(str, 0, max-3) + "..."

    // 指定偏移位置的缩略
    String abbreviate(final String str, final int offset, final int maxWidth)

    // 可指定缩减字符的省略符号
    public static String abbreviate(String str,String abbrevMarker,int maxWidth)

    编码

    1
    2
    3
    4
    5
    6
    // 将字节数组转换为指定编码的字符串
    public static String toEncodedString(byte[] bytes,Charset charset)
    应用场景:系统间交互时,字符编码不一致,如对方传递的参数编码为GB2312,我方编码为UTF-8,可通过该方法进行转换

    //转换unicode位码
    public static int[] toCodePoints(CharSequence str)

    字符串处理

    不改变字符串实质内容,对首尾以及中间的空白字符进行处理

    移除空白

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // trim类与jdk差异不大,去除包含控制字符(ascii码<=32)在内的控制字符(底层应用没做过,有可能会用到控制字符吧),主要是增加了对null的处理
    String trim(final String str)

    // 增加了空串的处理,null、""、" "直接输出为null
    String trimToNull(final String str)

    // 增加了空串的处理,null、""、" "直接输出为""
    String trimToEmpty(final String str)

    // strip类则做了很多增强,通过重载方法实现了很多其他功能,建议在开发中使用strip类
    // 注意:全角空格并不在处理范围内


    // 从首尾去除空格
    String strip(final String str)

    // 如果strip后的字符串为空("")或null,则返回null
    String stripToNull(String str)

    // 如果strip后的字符串为空("")或null,则返回""
    String stripToEmpty(final String str)

    // 去除指定字符串
    strip(String str, final String stripChars)

    // 从字符串的开头去除指定字符串
    String stripStart(final String str, final String stripChars)

    // 从字符串的尾部去除指定字符串
    String stripEnd(final String str, final String stripChars)

    // 批量移除所有字符串的 空格字符
    String[] stripAll(final String... strs)

    // 批量移除所有字符串的 指定字符
    String[] stripAll(final String[] strs, final String stripChars)

    //去除声调音标,官方举例是将 'à' 转换为'a',很生僻,基本不会用到,不确定汉语拼音的音标是否能处理
    public static String stripAccents(String input)

    // 按照定义删除字符串中的所有空格
    String deleteWhitespace(final String str)

    // 使用trim(String)删除首尾空格,然后用单个空格替换空格字符序列
    String normalizeSpace(final String str)

    去除换行

    1
    2
    // 去除结尾的一处换行符,包括三种情况 \r \n \r\n
    String chomp(final String str)

    去间隔符

    1
    2
    3
    // 去除末尾一个字符,常见使用场景是通过循环处理使用间隔符拼装的字符串,去除间隔符
    // 注意:使用时需确保最后一位一定是间隔符,否则有可能破坏正常数据
    String chop(final String str)

    去除非数字

    1
    2
    // 去除所有非数字字符,将剩余的数字字符拼接成字符串
    public static String getDigits(String str)

    编辑字符串

    分割字符串

    jdk中的split使用正则表达式匹配,而字符串分割最常用场景是如下这种根据间隔符分割;虽然split的方式也能实现效果,但是还有有点别扭,而在StringUtils就是通过字符串匹配,而不是正则表达式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 不设置间隔符,默认使用空白字符分割
    public static String[] split(String str)

    // 根据指定的间隔符分割
    String[] split(final String str, final char separatorChar)

    // 限定返回,贪婪匹配
    String[] splitByWholeSeparator(final String str, final String separator)

    // 分割字符串过程中会按照每个分隔符进行分割,不忽略任何空白项(splitByWholeSeparatorPreserveAllTokens与其一样)
    String[] splitPreserveAllTokens(final String str)

    // 根据字符类型分割,同一类划为一个数组元素,驼峰命名情况下,最后一个大写字母归属后面元素而不是前面
    String[] splitByCharacterType(final String str)

    合并字符串

    jdk使用concat方法,StringUtils使用join,这是一个泛型方法,建议实际使用过程中,还是只对String使用,不要对数值类型进行合并,会导致代码可读性降低
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 默认合并,注意:自动去除空白字符或null元素
    public static <T> String join(T... elements)

    // 使用指定间隔符合并,注意:保留空白字符或null元素
    public static String join(Object[] array,char separator)

    // 将提供的数组的元素连接到包含提供的元素列表的单个String中
    String join(final Object[] array, final char separator, final int startIndex, final int endIndex)

    // 将提供的Iterator的元素连接到包含提供的元素的单个String中
    String join(final Iterator<?> iterator, final char separator)

    // 将提供的List的元素连接到包含提供的元素的单个String中
    String join(final List<?> list, final String separator, final int startIndex, final int endIndex)

    截取字符串

    substring和truncate基本用法同jdk,内部处理异常
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    // 截取字符串,保留maxWidth长度
    String truncate(final String str, final int maxWidth)

    // 截取字符串,允许左便宜offset位,保留maxWidth长度
    String truncate(final String str, final int offset, final int maxWidth)

    // 从指定的String获取一个子字符串,避免出现异常; start表示从左侧开始截取
    String substring(final String str, int start)

    // 从指定的String获取一个子字符串;位置从start到end(不包括end)
    String substring(final String str, int start, int end)

    // 获取字符串最左边的len字符
    String left(final String str, final int len)

    // 获取字符串最右边的len字符
    String right(final String str, final int len)

    // 从字符串的中间len个字符,从pos位置开始偏移
    String mid(final String str, int pos, final int len)

    // 截取第一次出现分隔符之前的子字符串.分隔符不返回
    String substringBefore(final String str, final String separator)

    // 截取第一次出现分隔符之后的子字符串.分隔符不返回
    String substringAfter(final String str, final String separator)

    // 截取最后一次出现分隔符前面的子字符串.分隔符不返回
    String substringBeforeLast(final String str, final String separator)

    // 截取最后一次出现分隔符后面的子字符串.分隔符不返回
    String substringAfterLast(final String str, final String separator)

    // 截取tag所包含的中间字符串,tag不返回
    String substringBetween(final String str, final String tag)

    // 获取在open与close之间的字符串.仅返回第一个匹配项
    String substringBetween(final String str, final String open, final String close)

    // 获取在open与close之间的字符串.返回所有匹配项的数组
    String[] substringsBetween(final String str, final String open, final String close)

    移除字符串

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 当指定的字符串位于源字符串的开头时才删除它,否则返回源字符串
    String removeStart(final String str, final String remove)

    // 忽略大小写位于开头才移除它
    String removeStartIgnoreCase(final String str, final String remove)

    // 当指定的字符串位于源字符串的结尾时才删除它,否则返回源字符串
    String removeEnd(final String str, final String remove)

    // 从源字符串中删除所有出现的子字符串
    String remove(final String str, final String remove)

    // 忽略大小写
    String removeIgnoreCase(final String str, final String remove)

    替换字符串

    jdk中使用replace,StringUtils使用同样名字,默认替换掉所有匹配项,扩展实现了忽略大小写、只替换一次、指定最大替换次数等
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 将text中的searchString替换为replacement,只替换一次
    String replaceOnce(final String text, final String searchString, final String replacement)

    // 替换所有出现的地方
    String replace(final String text, final String searchString, final String replacement)

    // 将text中的searchString替换为replacement,替换max次(0代表不做替换,-1代表替换所有)
    String replace(final String text, final String searchString, final String replacement, final int max)

    // 将一个字符串中所有出现的字符替换为另一个
    String replaceChars(final String str, final char searchChar, final char replaceChar)

    // 一次性替换字符串中的多个字符。
    String replaceChars(final String str, final String searchChars, String replaceChars)

    覆盖字符串

    典型应用场景,隐藏字符串如证件号码、地址或手机号码中部分字符
    1
    2
    // 用另一个字符串从start到end覆盖一个字符串的一部分
    String overlay(final String str, String overlay, int start, int end)

    生成字符串

    1
    2
    3
    4
    5
    // 重复str字符串repeat次以形成一个新的字符串
    String repeat(final String str, final int repeat)

    // 重复str字符串repeat次以形成一个新的字符串,每次注入一个字符串分隔符
    String repeat(final String str, final String separator, final int repeat)

    前缀和后缀

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // 追加后缀,如只有两个参数,则是无条件追加,超过两个参数,是在不匹配suffixes任何情况下才追加
    public static String appendIfMissing(String str,CharSequence suffix,CharSequence... suffixes)
    public static String appendIfMissingIgnoreCase(String str,CharSequence suffix,CharSequence... suffixes)

    //追加前缀,如只有两个参数,则是无条件追加,超过两个参数,是在不匹配prefixes任何情况下才追加
    public static String prependIfMissing(String str,CharSequence prefix,CharSequence... prefixes)
    public static String prependIfMissingIgnoreCase(String str,CharSequence prefix,CharSequence... prefixes)

    // 无条件同时增加前缀和后缀
    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)

    其他

    计算匹配次数

    1
    2
    // 计算指定字符串出现的次数
    int countMatches(final CharSequence str, final CharSequence sub)

    默认值处理

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // 获取默认字符串,null及空格将会返回"",其他情况返回原始字符串
    public static String defaultString(String str)

    // 获取默认字符串,第一个参数为null及空格将会返回第二个参数指定值,其他情况返回原始字符串
    public static String defaultString(String str,String defaultStr)

    // 其他处理,返回数组中第一个不为空白或不为空的元素
    public static <T extends CharSequence> T firstNonBlank(T... values)
    public static <T extends CharSequence> T firstNonEmpty(T... values)

    //其他处理,如果为空白或空,返回指定值
    public static <T extends CharSequence> T defaultIfBlank(T str,T defaultStr)
    public static <T extends CharSequence> T defaultIfEmpty(T str,T defaultStr)

    字符串差异

    1
    2
    // 返回字符串差异部分,实用性差,不建议使用
    public static String difference(String str1,String str2)

取字符串相同的前缀

1
2
// 取字符串相同前缀
String getCommonPrefix(final String... strs)

getLevenshteinDistance

文章作者: Eric Liang
文章链接: https://ericql.github.io/2019/11/12/01-Java%E5%9F%BA%E7%A1%80%E7%AF%87/01-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86%E7%82%B9/String/StringUtils%E8%A7%A3%E6%9E%90/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Eric Liang
打赏
  • 微信
  • 支付宝