Java字符串处理工具类

        字符串是在程序开发中最常见的,经过多年不断积累,相关的工具类已经非常庞大,为了方便大家了解,这里根据个人开发经验,进行整理和归类,提供方便、简化的字符串处理方法,以支持大家在应用程序中更轻松地处理字符串。当然,日常开发中一般不会自己去编写工具类,更多是使用已经比较成熟的第三方库中提供的工具类,例如org.apache.commons.lang.StringUtils。


基本概念

几个概念先明确下:
1.null:String是引用类型而不是基本类型,所以取值可以为null
2.空串:即不包含任何元素的字符串,表示为""
3.空格:即" ",对应ascii码是32
4.空白字符:是一组非可见的字符,对于文本处理来说,除了空格外,通常包括tab(\t)、回车(\r)、换行(\n)、垂直制表符(\v)、换页符(\f),当然,windows系统常用的回车换行的组合(\r\n)也算在其中。

1 判断与验证

根据特定规则判断,不改变字符串自身

1.1判断是否包含内容

1)isEmpty和isNotEmpty方法

判断是否为null或空串

    /**
     * 判断字符串是否为空(null或空串)
     *
     * @param str 要判断的字符串
     * @return 如果字符串为空则返回true,否则返回false
     */
    public static boolean isEmpty(String str) {
        return str == null || str.isEmpty();
    }

    /**
     * 判断字符串是否不为空(null或空串)
     *
     * @param str 要判断的字符串
     * @return 如果字符串为空则返回true,否则返回false
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

示例

StringUtils.isEmpty(null);           // true
StringUtils.isEmpty("");             // true
StringUtils.isEmpty("  ");           // false
StringUtils.isEmpty("not empty");    // false

2)isBlank和isNotBlank方法

包含所有空白字符(空格、tab、换行、回车等)的判定

    /**
     * 判断字符串是否为空白
     * 
     * @param str
     * @return
     */
    public static boolean isBlank(String str) {
        if(str == null || str.length() == 0){
            return true;
        } else {
            for(char c : str.toCharArray()) {
                if (!Character.isWhitespace(c)) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 判断字符串是否不为空白
     * 
     * @param str
     * @return
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

3)hasLength方法

检查字符串是否有长度(非null且长度大于0)

    /**
     * 检查字符串是否有长度(非 null 且长度大于 0)
     *
     * @param str
     * @return
     */
    public static boolean hasLength(String str) {
        return str != null && !str.isEmpty();
    }

    /**
     * 检查字符串是否有长度(非 null 且长度大于 0)
     *
     * @param str
     * @return
     */
    public static boolean hasLength(CharSequence str) {
        return str != null && str.length() > 0;
    }

示例

StringUtils.hasLength(null);         // false
StringUtils.hasLength("");           // false
StringUtils.hasLength("  ");         // true
StringUtils.hasLength("not empty");  // true

1.2 比较字符串

基本用法equals、equalsIgnoreCase、compare、compareIgnoreCase

1)equals和equalsIgnoreCase方法:

    /**
     * 判断两个字符串是否相等
     *
     * @param str1 字符串1
     * @param str2 字符串2
     * @return 如果两个字符串相等则返回true,否则返回false
     */
    public static boolean equals(String str1, String str2) {
        if (str1 == str2) {
            return true;
        } else if (str1 != null && str2 != null) {
            return str1.equals(str2);
        } else {
            return false;
        }
    }

    /**
     * 判断两个字符串是否相等(忽略大小写)
     *
     * @param str1 字符串1
     * @param str2 字符串2
     * @return 如果两个字符串相等则返回true,否则返回false
     */
    public static boolean equalsIgnoreCase(String str1, String str2) {
        if (str1 == str2) {
            return true;
        } else if (str1 != null && str2 != null) {
            return str1.equalsIgnoreCase(str2);
        } else {
            return false;
        }
    }

注:

        一般情况下String字符串和数组都不是基本数据类型,它们被当作类来处理,也就是我们所说的引用数据类型。对基本类型而言,使用==进行比较,是直接比较两个数据类型之间的数值;对于引用类型而言,使用==进行比较,是比较的两个数据类型之间的地址。因此我们比较字符串的时候,需要使用str.equals(str2) 而不是直接使用==进行比较。

//下面我们来了解字符串的常量池

String str="gre";

String str2="gre";

char[] chars={'g','r','e'};

String arraychar=new String(chars);

System.out.println(str==str2);//true

System.out.println(str==arraychar);//false

System.out.println(str2==arraychar);//false

        对于前面两个定义str和str2而言,str和str2当中所保存字符由于是相同的,因此jvm为了节约内存,就让这个字母在内存当中的地址是相同的,在java当中字符串是不可修改的缘故,因此str和str2指向的是同一个内存空间,在这个内存空间当中我们爆保存的是gre这三个单词的ASCii码,which are 97,98,99。而对于使用char所创建的String而言,我们开启了一个新的内存空间,因为在内存当中我们保存的是char型字符,which are 'g','r','e',在内存当中保存的东西不一样了,因此地址也就不一样了。我们用于比较的时候字符串又是引用类型,因此最后比较的是地址,地址不一样就会输出false,这也是会最终呈持续的后面两行会输出false的缘故。

2)compare和compareIgnoreCase方法:

    /**
     * 比较两个字符串的大小
     *
     * @param str1 字符串1
     * @param str2 字符串2
     * @return 返回一个整数值,用于表示比较的结果
     */
    public static int compare(String str1, String str2) {
        return compare(str1, str2, true);
    }

    /**
     * 比较两个字符串的大小
     *
     * @param str1 字符串1
     * @param str2 字符串2
     * @param nullIsLess null值是是否是小值
     * @return 返回一个整数值,用于表示比较的结果。如果star1小于star2,则返回负数;如果star1等于star2,则返回0;;如果star1大于star2,则返回正数
     */
    public static int compare(String str1, String str2, boolean nullIsLess) {
        if (str1 == str2) {
            return 0;
        } else if (str1 == null) {
            return nullIsLess ? -1 : 1;
        } else if (str2 == null) {
            return nullIsLess ? 1 : -1;
        } else {
            return str1.compareTo(str2);
        }
    }

    /**
     * 比较两个字符串的大小(忽略大小写)
     *
     * @param str1 字符串1
     * @param str2 字符串2
     * @return 返回一个整数值,用于表示比较的结果
     */
    public static int compareIgnoreCase(String str1, String str2) {
        return compareIgnoreCase(str1, str2, true);
    }

    /**
     * 比较两个字符串的大小(忽略大小写)
     *
     * @param str1 字符串1
     * @param str2 字符串2
     * @param nullIsLess null值是是否是小值
     * @return 返回一个整数值,用于表示比较的结果。如果star1小于star2,则返回负数;如果star1等于star2,则返回0;;如果star1大于star2,则返回正数
     */
    public static int compareIgnoreCase(String str1, String str2, boolean nullIsLess) {
        if (str1 == str2) {
            return 0;
        } else if (str1 == null) {
            return nullIsLess ? -1 : 1;
        } else if (str2 == null) {
            return nullIsLess ? 1 : -1;
        } else {
            return str1.compareToIgnoreCase(str2);
        }
    }

1.3 检验字符串

通过一系列实现好的方法,来快速返回是否符合特定规则。

1)isNumeric和isNumericSpace方法(注意:小数点和正负号,都会判定为false)

    /**
     * 判断字符串是否为数字
     *
     * @param str 要判断的字符串
     * @return 如果字符串为数字则返回true,否则返回false
     */
    public static boolean isNumeric(String str) {
        if (isEmpty(str)) {
            return false;
        }
        for (char c : str.toCharArray()) {
            if (!Character.isDigit(c)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符串是否只包含数字和空格
     *
     * @param str 要判断的字符串
     * @return 如果字符串为数字则返回true,否则返回false
     */
    public static boolean isNumericSpace(String str) {
        if (str == null) {
            return false;
        } else {
            for (char c : str.toCharArray()) {
                if (c != ' ' && !Character.isDigit(c)) {
                    return false;
                }
            }
            return true;
        }
    }

2)isWhitespace方法

    /**
     * 判定是否只包括空白字符
     *
     * @param str
     * @return
     */
    public static boolean isWhitespace(String str) {
        if (str == null) {
            return false;
        } else {
            for (char c : str.toCharArray()) {
                if (!Character.isWhitespace(c)) {
                    return false;
                }
            }
            return true;
        }
    }

3)isAllUpperCase、isAllLowerCase和isMixedCase方法

    /**
     * 判定是否全部为大写
     *
     * @param str
     * @return
     */
    public static boolean isAllUpperCase(String str) {
        if (isEmpty(str)) {
            return false;
        } else {
            for (char c : str.toCharArray()) {
                if (!Character.isUpperCase(c)) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 判定是否全部为小写
     *
     * @param str
     * @return
     */
    public static boolean isAllLowerCase(String str) {
        if (isEmpty(str)) {
            return false;
        } else {
            for (char c : str.toCharArray()) {
                if (!Character.isLowerCase(c)) {
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * 判定是否混合大小写(注意:包含其他字符,如空格,不影响结果判定)
     *
     * @param str
     * @return
     */
    public static boolean isMixedCase(String str) {
        if (!isEmpty(str) && str.length() != 1) {
            boolean containsUppercase = false;
            boolean containsLowercase = false;
            for (char c : str.toCharArray()) {
                if (containsUppercase && containsLowercase) {
                    return true;
                }
                if (Character.isUpperCase(c)) {
                    containsUppercase = true;
                } else if (Character.isLowerCase(c)) {
                    containsLowercase = true;
                }
            }
            return containsUppercase && containsLowercase;
        } else {
            return false;
        }
    }

1.4 包含字符串

1)contains方法

    /**
     * 判断字符串是否包含指定子字符串
     *
     * @param str 要判断的字符串
     * @param searchStr 子字符串
     * @return 如果字符串包含指定子字符串则返回true,否则返回false
     */
    public static boolean contains(String str, String searchStr) {
        if (str != null && searchStr != null) {
            return str.contains(searchStr);
        } else {
            return false;
        }
    }

2)containsWhitespace方法

    /**
     * 判断是否包含空白字符串
     *
     * @param str
     * @return
     */
    public static boolean containsWhitespace(String str) {
        if (isEmpty(str)) {
            return false;
        } else {
            for(char c : str.toCharArray()){
                if (Character.isWhitespace(c)) {
                    return true;
                }
            }
            return false;
        }
    }

1.5 起止字符判定

1)startsWith 和 startsWithIgnoreCase方法

    /**
     * 判断字符串是否以指定的前缀开始
     *
     * @param str 要判断的字符串
     * @param prefix 前缀
     * @return 如果字符串以指定的前缀开始则返回true,否则返回false
     */
    public static boolean startsWith(String str, String prefix) {
        if (str != null && prefix != null) {
            return str.startsWith(prefix);
        } else {
            return str == prefix;
        }
    }

    /**
     * 判断字符串是否以指定的前缀开始(忽略大小写)
     *
     * @param str 要判断的字符串
     * @param prefix 前缀
     * @return 如果字符串以指定的前缀开始则返回true,否则返回false
     */
    public static boolean startsWithIgnoreCase(String str, String prefix) {
        return str != null && prefix != null && str.length() >= prefix.length() && str.regionMatches(true, 0, prefix, 0, prefix.length());
    }

2)endsWith 和 endsWithIgnoreCase方法

    /**
     * 判断字符串是否以指定的后缀结束
     *
     * @param str 要判断的字符串
     * @param suffix 后缀
     * @return 如果字符串以指定的后缀结束则返回true,否则返回false
     */
    public static boolean endsWith(String str, String suffix) {
        if (str != null && suffix != null) {
            return str.endsWith(suffix);
        } else {
            return str == suffix;
        }
    }

    /**
     * 判断字符串是否以指定的后缀结束(忽略大小写)
     *
     * @param str 要判断的字符串
     * @param suffix 后缀
     * @return 如果字符串以指定的后缀结束则返回true,否则返回false
     */
    public static boolean endsWithIgnoreCase(String str, String suffix) {
        return str != null && suffix != null && str.length() >= suffix.length() && str.regionMatches(true, str.length() - suffix.length(), suffix, 0, suffix.length());
    }

2 处理字符串

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

2.1 移除空白字符

1)trim方法
trim方法与jdk差异不大,去除首尾的包含控制字符(ascii码<=32)在内的控制字符),主要是增加了对null的处理。

    /**
     * 去除字符串两端的空格
     *
     * @param str 要处理的字符串
     * @return 去除两端空格后的字符串
     */
    public static String trim(String str) {
        return str == null ? null : str.trim();
    }

2)trimAllWhitespace方法

去除字符串中所有的空白字符(包含空格、制表符、换行符等)

    /**
     * 去除字符串中的所有空白字符,‌包括空格、‌制表符、‌换行符等
     *
     * @param str
     * @return
     */
    public static String trimAllWhitespace(String str) {
        if (isEmpty(str)) {
            return str;
        } else {
            int len = str.length();
            StringBuilder sb = new StringBuilder(str.length());
            for(int i = 0; i < len; ++i) {
                char c = str.charAt(i);
                if (!Character.isWhitespace(c)) {
                    sb.append(c);
                }
            }
            return sb.toString();
        }
    }

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

    /**
     * 去除字符串两端的空格
     *
     * @param str
     * @return
     */
    public static String strip(String str) {
        return strip(str, (String)null);
    }

    /**
     * 去除指定字符串
     *
     * @param str
     * @param stripChars
     * @return
     */
    public static String strip(String str, String stripChars) {
        str = stripStart(str, stripChars);
        return stripEnd(str, stripChars);
    }

    public static String stripStart(String str, String stripChars) {
        int strLen = str == null ? 0 : str.length();
        if (strLen == 0) {
            return str;
        } else {
            int start = 0;
            if (stripChars == null) {
                while(start != strLen && Character.isWhitespace(str.charAt(start))) {
                    ++start;
                }
            } else {
                if (stripChars.isEmpty()) {
                    return str;
                }
                while(start != strLen && stripChars.indexOf(str.charAt(start)) != -1) {
                    ++start;
                }
            }
            return str.substring(start);
        }
    }

    public static String stripEnd(String str, String stripChars) {
        int end = str == null ? 0 : str.length();
        if (end == 0) {
            return str;
        } else {
            if (stripChars == null) {
                while(end != 0 && Character.isWhitespace(str.charAt(end - 1))) {
                    --end;
                }
            } else {
                if (stripChars.isEmpty()) {
                    return str;
                }
                while(end != 0 && stripChars.indexOf(str.charAt(end - 1)) != -1) {
                    --end;
                }
            }
            return str.substring(0, end);
        }
    }

    /**
     * 批量去除操作
     *
     * @param strs
     * @return
     */
    public static String[] stripAll(String... strs) {
        return stripAll(strs, (String)null);
    }

    /**
     * 批量去除操作
     *
     * @param strs
     * @param stripChars
     * @return
     */
    public static String[] stripAll(String[] strs, String stripChars) {
        int strsLen = strs == null ? 0 : Array.getLength(strs);
        if (strsLen == 0) {
            return strs;
        } else {
            String[] newArr = new String[strsLen];
            for(int i = 0; i < strsLen; ++i) {
                newArr[i] = strip(strs[i], stripChars);
            }
            return newArr;
        }
    }

3)deleteWhitespace方法

对字符串基本处理的复合应用,将字符串中所有空白字符去除

    /**
     * 将字符串中所有空白字符去除
     *
     * @param str
     * @return
     */
    public static String deleteWhitespace(String str) {
        if (isEmpty(str)) {
            return str;
        } else {
            int sz = str.length();
            char[] chs = new char[sz];
            int count = 0;

            for(int i = 0; i < sz; ++i) {
                if (!Character.isWhitespace(str.charAt(i))) {
                    chs[count++] = str.charAt(i);
                }
            }

            if (count == sz) {
                return str;
            } else if (count == 0) {
                return "";
            } else {
                return new String(chs, 0, count);
            }
        }
    }

4)normalizeSpace方法

去除首尾,但中间的空白字符,替换为单个空格

    /**
     * 去除首尾空白字符,但中间的空白字符,替换为单个空格
     *
     * @param str
     * @return
     */
    public static String normalizeSpace(String str) {
        if (isEmpty(str)) {
            return str;
        } else {
            int size = str.length();
            char[] newChars = new char[size];
            int count = 0;
            int whitespacesCount = 0;
            boolean startWhitespaces = true;

            for(int i = 0; i < size; ++i) {
                char actualChar = str.charAt(i);
                boolean isWhitespace = Character.isWhitespace(actualChar);
                if (isWhitespace) {
                    if (whitespacesCount == 0 && !startWhitespaces) {
                        newChars[count++] = " ".charAt(0);
                    }
                    ++whitespacesCount;
                } else {
                    startWhitespaces = false;
                    newChars[count++] = actualChar == 160 ? 32 : actualChar;
                    whitespacesCount = 0;
                }
            }
            if (startWhitespaces) {
                return "";
            } else {
                return (new String(newChars, 0, count - (whitespacesCount > 0 ? 1 : 0))).trim();
            }
        }
    }

2.2 去除换行

1)chomp方法

去除结尾的一处换行符,包括三种情况 \r \n \r\n

    /**
     * 去除结尾的一处换行符,包括三种情况 \r \n \r\n
     *
     * @param str
     * @return
     */
    public static String chomp(String str) {
        if (isEmpty(str)) {
            return str;
        } else if (str.length() == 1) {
            char ch = str.charAt(0);
            return ch != '\r' && ch != '\n' ? str : "";
        } else {
            int lastIdx = str.length() - 1;
            char last = str.charAt(lastIdx);
            if (last == '\n') {
                if (str.charAt(lastIdx - 1) == '\r') {
                    --lastIdx;
                }
            } else if (last != '\r') {
                ++lastIdx;
            }

            return str.substring(0, lastIdx);
        }
    }

示例

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 去除间隔符

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

    /**
     * 去除结尾的间隔符
     *
     * @param str
     * @return
     */
    public static String chop(String str) {
        if (str == null) {
            return null;
        } else {
            int strLen = str.length();
            if (strLen < 2) {
                return "";
            } else {
                int lastIdx = strLen - 1;
                String ret = str.substring(0, lastIdx);
                char last = str.charAt(lastIdx);
                return last == '\n' && ret.charAt(lastIdx - 1) == '\r' ? ret.substring(0, lastIdx - 1) : ret;
            }
        }
    }

示例:

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 去除非数字

去除所有非数字字符,将剩余的数字字符拼接成字符串

    /**
     * 去除所有非数字字符,将剩余的数字字符拼接成字符串
     *
     * @param str
     * @return
     */
    public static String getDigits(String str) {
        if (isEmpty(str)) {
            return str;
        } else {
            int sz = str.length();
            StringBuilder strDigits = new StringBuilder(sz);
            for(int i = 0; i < sz; ++i) {
                char tempChar = str.charAt(i);
                if (Character.isDigit(tempChar)) {
                    strDigits.append(tempChar);
                }
            }
            return strDigits.toString();
        }
    }

示例:

StringUtils.getDigits("abc") = ""
StringUtils.getDigits("1000$") = "1000"
StringUtils.getDigits("1123~45") = "112345"
StringUtils.getDigits("(541) 754-3010") = "5417543010"

2.4 去除子字符串

1)delete方法

    /**
     * 去除所有匹配的子字符串
     *
     * @param inString
     * @param pattern
     * @return
     */
    public static String delete(String inString, String pattern) {
        return replace(inString, pattern, "");
    }

2)deleteAny方法

    /**
     * 去除子字符串中任意出现的字符
     *
     * @param inString
     * @param charsToDelete
     * @return
     */
    public static String deleteAny(String inString, String charsToDelete) {
        if (hasLength(inString) && hasLength(charsToDelete)) {
            StringBuilder sb = new StringBuilder(inString.length());
            for(int i = 0; i < inString.length(); ++i) {
                char c = inString.charAt(i);
                if (charsToDelete.indexOf(c) == -1) {
                    sb.append(c);
                }
            }
            return sb.toString();
        } else {
            return inString;
        }
    }

3.查找字符串

3.1 查找字符串

1)indexOf 和 lastIndexOf方法

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

    /**
     * 搜索字符串
     *
     * @param str
     * @param searchStr
     * @return 返回第一个匹配项的索引
     */
    public static int indexOf(String str, String searchStr) {
        return str != null && searchStr != null ? str.indexOf(searchStr) : -1;
    }

    /**
     * 搜索字符串以及指定起始搜索位置
     *
     * @param str
     * @param searchStr
     * @param fromIndex
     * @return 返回第一个匹配项的索引
     */
    public static int indexOf(String str, String searchStr, int fromIndex) {
        return str != null && searchStr != null ? str.indexOf(searchStr, fromIndex) : -1;
    }

    /**
     * 搜索字符
     *
     * @param str
     * @param searchChar
     * @return 返回第一个匹配项的索引
     */
    public static int indexOf(String str, int searchChar) {
        return str != null ? str.indexOf(searchChar) : -1;
    }

    /**
     * 搜索字符以及指定起始搜索位置
     *
     * @param str
     * @param searchChar
     * @param fromIndex
     * @return 返回第一个匹配项的索引
     */
    public static int indexOf(String str, int searchChar, int fromIndex) {
        return str != null ? str.indexOf(searchChar, fromIndex) : -1;
    }

    /**
     * 搜索字符串
     *
     * @param str
     * @param searchStr
     * @return 返回指定字符在此字符串中最后一次出现处的索引
     */
    public static int lastIndexOf(String str, String searchStr) {
        return str != null && searchStr != null ? str.lastIndexOf(searchStr) : -1;
    }

    /**
     * 搜索字符串以及指定起始搜索位置
     *
     * @param str
     * @param searchStr
     * @param fromIndex
     * @return 返回指定字符在此字符串中最后一次出现处的索引
     */
    public static int lastIndexOf(String str, String searchStr, int fromIndex) {
        return str != null && searchStr != null ? str.lastIndexOf(searchStr, fromIndex) : -1;
    }

    /**
     * 搜索字符
     *
     * @param str
     * @param searchChar
     * @return 返回指定字符在此字符串中最后一次出现处的索引
     */
    public static int lastIndexOf(String str, int searchChar) {
        return str != null ? str.lastIndexOf(searchChar) : -1;
    }

    /**
     * 搜索字符以及指定起始搜索位置
     *
     * @param str
     * @param searchChar
     * @param fromIndex
     * @return 返回指定字符在此字符串中最后一次出现处的索引
     */
    public static int lastIndexOf(String str, int searchChar, int fromIndex) {
        return str != null ? str.lastIndexOf(searchChar, fromIndex) : -1;
    }

3.2 尾部字符串

1)unqualify方法

    /**
     * 获取最后一个.之后的字符串
     *
     * @param qualifiedName
     * @return
     */
    public static String unqualify(String qualifiedName) {
        return unqualify(qualifiedName, '.');
    }

    /**
     * 获取最后一个指定分隔符之后的字符串
     *
     * @param qualifiedName
     * @param separator
     * @return
     */
    public static String unqualify(String qualifiedName, char separator) {
        if(isNotEmpty(qualifiedName)){
            int lastIndex = qualifiedName.lastIndexOf(separator);
            if(lastIndex >= 0){
                return qualifiedName.substring(lastIndex + 1);
            }
            return "";
        }
        return qualifiedName;
    }

4.编辑字符串

字符串的分割、合并、截取、替换

4.1 分割字符串

1)split 和 splitToList方法

jdk中的split使用正则表达式匹配,而字符串分割最常用场景是如下这种根据间隔符分割

String str=“he,ll,o”;
String [] reuslt=str.split(“,”);

    /**
     * 将字符串按照指定分隔符拆分为数组
     *
     * @param str 要拆分的字符串
     * @param delimiter 分隔符
     * @return 拆分后的字符串数组
     */
    public static String[] split(String str, String delimiter) {
        if (str == null) {
            return null;
        } else {
            return str.split(delimiter);
        }
    }

    /**
     * 将字符串按照指定分隔符拆分为列表
     *
     * @param str 要拆分的字符串
     * @param delimiter 分隔符
     * @return 拆分后的字符串列表
     */
    public static List<String> splitToList(String str, String delimiter) {
        if (str == null) {
            return null;
        } else {
            return Arrays.asList(str.split(delimiter));
        }
    }

4.2 合并字符串

1)join方法

jdk使用concat方法,这里使用join,这是一个泛型方法,建议实际使用过程中,还是只对String使用,不要对数值类型进行合并,会导致代码可读性降低
//默认合并,注意:自动去除空白字符或null元素

    /**
     * 合并字符串(自动去除空白字符或null元素)
     *
     * @param elements
     * @param <T>
     * @return
     */
    @SafeVarargs
    public static <T> String join(T... elements) {
        return join((Object[])elements, (String)null);
    }

    /**
     * 合并字符串(自动去除空白字符或null元素)
     *
     * @param array
     * @param delimiter
     * @return
     */
    public static String join(Object[] array, String delimiter) {
        return array == null ? null : join((Object[])array, delimiter, 0, array.length);
    }

    /**
     * 合并字符串(自动去除空白字符或null元素)
     *
     * @param array
     * @param delimiter
     * @param startIndex
     * @param endIndex
     * @return
     */
    public static String join(Object[] array, String delimiter, int startIndex, int endIndex) {
        if (array == null) {
            return null;
        } else if (endIndex - startIndex <= 0) {
            return "";
        } else {
            StringJoiner joiner = new StringJoiner(Objects.toString(delimiter, ""));
            for(int i = startIndex; i < endIndex; ++i) {
                joiner.add(Objects.toString(array[i], ""));
            }
            return joiner.toString();
        }
    }

示例:

StringUtils.join(null) = null
StringUtils.join([]) = ""
StringUtils.join([null]) = ""
StringUtils.join(["a", "b", "c"]) = "abc"
StringUtils.join([null, "", "a"]) = "a"
//使用指定间隔符合并,注意:保留空白字符或null元素
StringUtils.join(["a", "b", "c"], ';') = “a;b;c”
StringUtils.join([null, "", "a"], ';') = “;;a”

4.3 截取字符串

相关方法有多个,substring和truncate基本用法同jdk,内部处理异常

1)substring方法

    /**
     * 截取字符串
     *
     * @param str
     * @param start
     * @return
     */
    public static String substring(String str, int start) {
        if (str == null) {
            return null;
        } else {
            return str.substring(start);
        }
    }

    /**
     * 截取字符串
     *
     * @param str
     * @param start
     * @param end
     * @return
     */
    public static String substring(String str, int start, int end) {
        if (str == null) {
            return null;
        } else {
            return str.substring(start, end);
        }
    }

2)substringBefore和substringAfter方法

截取第一个指定字符前/后的字符串返回

    /**
     * 截取第一个指定字符前的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringBefore(String str, int separator) {
        if (isEmpty(str)) {
            return str;
        } else {
            int pos = str.indexOf(separator);
            return pos == -1 ? str : str.substring(0, pos);
        }
    }

    /**
     * 截取第一个指定字符前的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringBefore(String str, String separator) {
        if (!isEmpty(str) && separator != null) {
            if (separator.isEmpty()) {
                return "";
            } else {
                int pos = str.indexOf(separator);
                return pos == -1 ? str : str.substring(0, pos);
            }
        } else {
            return str;
        }
    }

    /**
     * 截取第一个指定字符后的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringAfter(String str, int separator) {
        if (isEmpty(str)) {
            return str;
        } else {
            int pos = str.indexOf(separator);
            return pos == -1 ? "" : str.substring(pos + 1);
        }
    }

    /**
     * 截取第一个指定字符后的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringAfter(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        } else if (separator == null) {
            return "";
        } else {
            int pos = str.indexOf(separator);
            return pos == -1 ? "" : str.substring(pos + separator.length());
        }
    }

3)substringBeforeLast 和 substringAfterLast方法

截取最后一个指定字符前/后的字符串返回

    /**
     * 截取最后一个指定字符前的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringBeforeLast(String str, String separator) {
        if (!isEmpty(str) && !isEmpty(separator)) {
            int pos = str.lastIndexOf(separator);
            return pos == -1 ? str : str.substring(0, pos);
        } else {
            return str;
        }
    }

    /**
     * 截取最后一个指定字符后的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringAfterLast(String str, int separator) {
        if (isEmpty(str)) {
            return str;
        } else {
            int pos = str.lastIndexOf(separator);
            return pos != -1 && pos != str.length() - 1 ? str.substring(pos + 1) : "";
        }
    }

    /**
     * 截取最后一个指定字符后的字符串返回
     *
     * @param str
     * @param separator
     * @return
     */
    public static String substringAfterLast(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        } else if (isEmpty(separator)) {
            return "";
        } else {
            int pos = str.lastIndexOf(separator);
            return pos != -1 && pos != str.length() - separator.length() ? str.substring(pos + separator.length()) : "";
        }
    }

4)substringBetween方法

    /**
     * 截取特定字符串中间部分
     *
     * @param str
     * @param tag
     * @return
     */
    public static String substringBetween(String str, String tag) {
        return substringBetween(str, tag, tag);
    }

    /**
     * 截取特定字符串中间部分
     *
     * @param str
     * @param open
     * @param close
     * @return 返回起止字符串中间的字符串,且只返回第一次匹配结果
     */
    public static String substringBetween(String str, String open, String close) {
        if (!ObjectUtils.allNotNull(new Object[]{str, open, close})) {
            return null;
        } else {
            int start = str.indexOf(open);
            if (start != -1) {
                int end = str.indexOf(close, start + open.length());
                if (end != -1) {
                    return str.substring(start + open.length(), end);
                }
            }
            return null;
        }
    }

    /**
     * 截取特定字符串中间部分
     *
     * @param str
     * @param open
     * @param close
     * @return 返回起止字符串中间的字符串,返回所有匹配结果
     */
    public static String[] substringsBetween(String str, String open, String close) {
        if (str != null && !isEmpty(open) && !isEmpty(close)) {
            int strLen = str.length();
            if (strLen == 0) {
                return new String[0];
            } else {
                int closeLen = close.length();
                int openLen = open.length();
                List<String> list = new ArrayList();
                int end;
                for(int pos = 0; pos < strLen - closeLen; pos = end + closeLen) {
                    int start = str.indexOf(open, pos);
                    if (start < 0) {
                        break;
                    }
                    start += openLen;
                    end = str.indexOf(close, start);
                    if (end < 0) {
                        break;
                    }
                    list.add(str.substring(start, end));
                }
                return list.isEmpty() ? null : (String[])list.toArray(new String[0]);
            }
        } else {
            return null;
        }
    }

5)left、right 和 mid方法

直接实现从左侧、右侧或中间截取指定位数,实用性高

    /**
     * 从左侧截取指定位数
     *
     * @param str
     * @param len
     * @return
     */
    public static String left(String str, int len) {
        if (str == null) {
            return null;
        } else if (len < 0) {
            return "";
        } else {
            return str.length() <= len ? str : str.substring(0, len);
        }
    }

    /**
     * 从右侧或截取指定位数
     *
     * @param str
     * @param len
     * @return
     */
    public static String right(String str, int len) {
        if (str == null) {
            return null;
        } else if (len < 0) {
            return "";
        } else {
            return str.length() <= len ? str : str.substring(str.length() - len);
        }
    }

    /**
     * 从中间截取指定位数
     *
     * @param str
     * @param pos
     * @param len
     * @return
     */
    public static String mid(String str, int pos, int len) {
        if (str == null) {
            return null;
        } else if (len >= 0 && pos <= str.length()) {
            if (pos < 0) {
                pos = 0;
            }
            return str.length() <= pos + len ? str.substring(pos) : str.substring(pos, pos + len);
        } else {
            return "";
        }
    }

6)truncate方法

    /**
     * 截断字符串到指定的长度
     *
     * @param str
     * @param maxWidth
     * @return 如果字符串的长度小于或等于指定的长度,‌则返回原始字符串;‌如果字符串的长度大于指定的长度,‌则截断字符串并返回截断后的字符串。‌
     */
    public static String truncate(String str, int maxWidth) {
        return truncate(str, 0, maxWidth);
    }

    /**
     * 截断字符串到指定的长度,指定起始位置
     *
     * @param str
     * @param offset
     * @param maxWidth
     * @return
     */
    public static String truncate(String str, int offset, int maxWidth) {
        if (offset < 0) {
            throw new IllegalArgumentException("offset cannot be negative");
        } else if (maxWidth < 0) {
            throw new IllegalArgumentException("maxWith cannot be negative");
        } else if (str == null) {
            return null;
        } else if (offset > str.length()) {
            return "";
        } else if (str.length() > maxWidth) {
            int ix = Math.min(offset + maxWidth, str.length());
            return str.substring(offset, ix);
        } else {
            return str.substring(offset);
        }
    }

4.4 替换字符串

1)replace方法

jdk中使用replace,这里使用同样名字,默认替换掉所有匹配项。

    /**
     * 替换字符串中的指定子字符串
     *
     * @param str 要替换的字符串
     * @param target 要被替换的子字符串
     * @param replacement 替换字符串
     * @return 替换后的字符串
     */
    public static String replace(String str, String target, String replacement) {
        if (!isEmpty(str) && !isEmpty(target) && replacement != null) {
            return str.replace(target, replacement);
        }
        return str;
    }

2)replaceAll方法

replaceAll方法是基于正则表达式的替换方法,可以替换所有匹配的子字符串。

    /**
     * 替换字符串中的匹配正则表达式的子字符串
     *
     * @param str 要替换的字符串
     * @param regex 正则表达式
     * @param replacement 替换字符串
     * @return 替换后的字符串
     */
    public static String replaceAll(String str, String regex, String replacement) {
        if (!isEmpty(str) && !isEmpty(regex) && replacement != null) {
            return str.replaceAll(regex, replacement);
        }
        return str;
    }

4.5.移除字符串

1)remove方法

    /**
     * 移除字符串
     *
     * @param str
     * @param remove
     * @return
     */
    public static String remove(String str, String remove) {
        return !isEmpty(str) && !isEmpty(remove) ? replace(str, remove, "") : str;
    }

    /**
     * 移除字符
     *
     * @param str
     * @param remove
     * @return
     */
    public static String remove(String str, char remove) {
        if (!isEmpty(str) && str.indexOf(remove) != -1) {
            char[] chars = str.toCharArray();
            int pos = 0;
            for(int i = 0; i < chars.length; ++i) {
                if (chars[i] != remove) {
                    chars[pos++] = chars[i];
                }
            }
            return new String(chars, 0, pos);
        } else {
            return str;
        }
    }

示例:

//注意,是第二个参数中所有字符,而不是匹配整个字符串

StringUtils.remove(“queued”, “ue”) = “qd”

2)removeStart 和 removeEnd方法

    /**
     * 移除开始位置指定字符串
     *
     * @param str
     * @param remove
     * @return
     */
    public static String removeStart(String str, String remove) {
        if (!isEmpty(str) && !isEmpty(remove)) {
            return str.startsWith(remove) ? str.substring(remove.length()) : str;
        } else {
            return str;
        }
    }

    /**
     * 移除开始位置指定字符串
     *
     * @param str
     * @param remove
     * @return
     */
    public static String removeEnd(String str, String remove) {
        if (!isEmpty(str) && !isEmpty(remove)) {
            return str.endsWith(remove) ? str.substring(0, str.length() - remove.length()) : str;
        } else {
            return str;
        }
    }

4.6.覆盖部分字符串

1)overlay方法

典型应用场景,隐藏字符串如证件号码、地址或手机号码中部分字符

    /**
     * 覆盖部分字符串
     *
     * @param str
     * @param overlay
     * @param start
     * @param end
     * @return
     */
    public static String overlay(String str, String overlay, int start, int end) {
        if (str == null) {
            return null;
        } else {
            if (overlay == null) {
                overlay = "";
            }
            int len = str.length();
            //如果是负数,则表示添加到开始
            if (start < 0) {
                start = 0;
            }
            //如果超出字符串自身长度,添加到末尾
            if (start > len) {
                start = len;
            }
            //如果是负数,则表示添加到开始
            if (end < 0) {
                end = 0;
            }
            //如果超出字符串自身长度,添加到末尾
            if (end > len) {
                end = len;
            }
            //判断哪个数字小,哪个就是起始值
            if (start > end) {
                int temp = start;
                start = end;
                end = temp;
            }
            return str.substring(0, start) + overlay + str.substring(end);
        }
    }

4.7 生成字符串

1)repeat方法

根据指定信息产生字符串

    /**
     * 生成重复指定次数的字符串
     *
     * @param str 要重复的字符串
     * @param repeatCount 重复次数
     * @return 重复指定次数后的字符串
     */
    public static String repeat(String str, int repeatCount) {
        if (str == null) {
            return null;
        } else if (repeatCount <= 0) {
            return "";
        } else {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < repeatCount; i++) {
                sb.append(str);
            }
            return sb.toString();
        }
    }

    /**
     * 生成重复指定次数的字符串
     * 
     * @param ch
     * @param repeat
     * @return
     */
    public static String repeat(char ch, int repeat) {
        if (repeat <= 0) {
            return "";
        } else {
            char[] buf = new char[repeat];
            Arrays.fill(buf, ch);
            return new String(buf);
        }
    }

    /**
     * 生成重复指定次数的字符串,并使用分隔符进行分隔
     * 
     * @param str
     * @param separator
     * @param repeat
     * @return
     */
    public static String repeat(String str, String separator, int repeat) {
        if (str != null && separator != null) {
            String result = repeat(str + separator, repeat);
            return removeEnd(result, separator);
        } else {
            return repeat(str, repeat);
        }
    }

示例:

StringUtils.repeat(“a”, 3) = “aaa”
StringUtils.repeat(“ab”, 2) = “abab”

StringUtils.repeat(“?”, ", ", 3) = “?, ?, ?”

4.8 前缀和后缀

1)prepend 和 prependIfMissing方法

    /**
     * 追加前缀
     *
     * @param str
     * @param prefix
     * @return
     */
    public static String prepend(String str, String prefix) {
        return prependIfMissing(str, prefix);
    }

    /**
     * 追加前缀
     * (如只有str和prefix两个参数,则是无条件追加,超过两个参数(即prefixes不为空),则是在不匹配prefixes任何情况下才追加)
     *
     * @param str
     * @param prefix
     * @param prefixes
     * @return
     */
    public static String prependIfMissing(String str, String prefix, String... prefixes) {
        if (str != null && !isEmpty(prefix) && !startsWith(str, prefix)) {
            //在不匹配prefixes任何情况下才追加
            if (prefixes != null && Array.getLength(prefixes) > 0) {
                String[] prefixArr = prefixes;
                int len = prefixes.length;
                for(int i = 0; i < len; ++i) {
                    String p = prefixArr[i];
                    if (startsWith(str, p)) {
                        return str;
                    }
                }
            }
            return prefix.toString() + str;
        } else {
            return str;
        }
    }

2)append 和 appendIfMissing方法

    /**
     * 追加后缀
     *
     * @param str
     * @param suffix
     * @return
     */
    public static String append(String str, String suffix) {
        return appendIfMissing(str, suffix);
    }

    /**
     * 追加后缀
     * (如只有str和suffix两个参数,则是无条件追加,超过两个参数,是在不匹配suffixes任何情况下才追加)
     *
     * @param str
     * @param suffix
     * @param suffixes
     * @return
     */
    public static String appendIfMissing(String str, String suffix, String... suffixes) {
        if (str != null && !isEmpty(suffix) && !endsWith(str, suffix)) {
            //在不匹配suffixes任何情况下才追加
            if (suffixes != null && Array.getLength(suffixes) > 0) {
                String[] suffixArr = suffixes;
                int len = suffixes.length;
                for(int i = 0; i < len; ++i) {
                    String s = suffixArr[i];
                    if (endsWith(str, s)) {
                        return str;
                    }
                }
            }
            return str + suffix.toString();
        } else {
            return str;
        }
    }

3)wrap 和 wrapIfMissing方法

    /**
     * 无条件同时增加前缀和后缀
     *
     * @param str
     * @param wrapWith
     * @return
     */
    public static String wrap(String str, char wrapWith) {
        return !isEmpty(str) && wrapWith != 0 ? wrapWith + str + wrapWith : str;
    }

    /**
     * 无条件同时增加前缀和后缀
     *
     * @param str
     * @param wrapWith
     * @return
     */
    public static String wrap(String str, String wrapWith) {
        return !isEmpty(str) && !isEmpty(wrapWith) ? wrapWith.concat(str).concat(wrapWith) : str;
    }

    /**
     * 有条件同时增加前缀和后缀
     *
     * @param str
     * @param wrapWith
     * @return
     */
    public static String wrapIfMissing(String str, char wrapWith) {
        if (!isEmpty(str) && wrapWith != 0) {
            boolean wrapStart = str.charAt(0) != wrapWith;
            boolean wrapEnd = str.charAt(str.length() - 1) != wrapWith;
            if (!wrapStart && !wrapEnd) {
                return str;
            } else {
                StringBuilder builder = new StringBuilder(str.length() + 2);
                if (wrapStart) {
                    builder.append(wrapWith);
                }
                builder.append(str);
                if (wrapEnd) {
                    builder.append(wrapWith);
                }
                return builder.toString();
            }
        } else {
            return str;
        }
    }

    /**
     * 有条件同时增加前缀和后缀
     * 
     * @param str
     * @param wrapWith
     * @return
     */
    public static String wrapIfMissing(String str, String wrapWith) {
        if (!isEmpty(str) && !isEmpty(wrapWith)) {
            boolean wrapStart = !str.startsWith(wrapWith);
            boolean wrapEnd = !str.endsWith(wrapWith);
            if (!wrapStart && !wrapEnd) {
                return str;
            } else {
                StringBuilder builder = new StringBuilder(str.length() + wrapWith.length() + wrapWith.length());
                if (wrapStart) {
                    builder.append(wrapWith);
                }
                builder.append(str);
                if (wrapEnd) {
                    builder.append(wrapWith);
                }
                return builder.toString();
            }
        } else {
            return str;
        }
    }

4)unwrap方法

    /**
     * 去除前缀和后缀
     *
     * @param str
     * @param wrapChar
     * @return
     */
    public static String unwrap(String str, char wrapChar) {
        if (!isEmpty(str) && wrapChar != 0 && str.length() != 1) {
            if (str.charAt(0) == wrapChar && str.charAt(str.length() - 1) == wrapChar) {
                int endIndex = str.length() - 1;
                return str.substring(1, endIndex);
            } else {
                return str;
            }
        } else {
            return str;
        }
    }

    /**
     * 去除前缀和后缀
     *
     * @param str
     * @param wrapToken
     * @return
     */
    public static String unwrap(String str, String wrapToken) {
        if (!isEmpty(str) && !isEmpty(wrapToken) && str.length() >= 2 * wrapToken.length()) {
            if (startsWith(str, wrapToken) && endsWith(str, wrapToken)) {
                int startIndex = str.indexOf(wrapToken);
                int endIndex = str.lastIndexOf(wrapToken);
                int wrapLength = wrapToken.length();
                if (startIndex != -1 && endIndex != -1) {
                    return str.substring(startIndex + wrapLength, endIndex);
                }
            }
            return str;
        } else {
            return str;
        }
    }

4.9 添加双引号 

1)quote 和 quoteIfString 方法

    /**
     * 在字符串两端添加双引号
     *
     * @param str
     * @return
     */
    public static String quote(String str) {
        return str != null ? "'" + str + "'" : null;
    }

    /**
     * 在字符串两端添加双引号
     *
     * @param obj
     * @return
     */
    public static Object quoteIfString(Object obj) {
        return obj instanceof String ? quote((String)obj) : obj;
    }

示例

StringUtils.quote("example");   // "\"example\""

5.字符串转换

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

5.1 大小写转换

1)upperCase 和 lowerCase方法

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

    /**
     * 将字符串转换为大写
     *
     * @param str 要转换的字符串
     * @return 转换为大写后的字符串
     */
    public static String upperCase(String str) {
        return str == null ? null : str.toUpperCase();
    }

    /**
     * 将字符串转换为大写
     *
     * @param str 要转换的字符串
     * @param locale
     * @return 转换为大写后的字符串
     */
    public static String upperCase(String str, Locale locale) {
        locale = locale != null ? locale : Locale.getDefault();
        return str == null ? null : str.toUpperCase(locale);
    }

    /**
     * 将字符串转换为小写
     *
     * @param str
     * @return
     */
    public static String lowerCase(String str) {
        return str == null ? null : str.toLowerCase();
    }

    /**
     * 将字符串转换为小写
     *
     * @param str
     * @param locale
     * @return
     */
    public static String lowerCase(String str, Locale locale) {
        locale = locale != null ? locale : Locale.getDefault();
        return str == null ? null : str.toLowerCase(locale);
    }

2)capitalize 和 uncapitalize方法

    /**
     * 将字符串转换为首字母大写
     *
     * @param str 要转换的字符串
     * @return 首字母大写的字符串
     */
    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }

    /**
     * 将字符串转换为首字母小写
     *
     * @param str 要转换的字符串
     * @return 首字母小写的字符串
     */
    public static String uncapitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return Character.toLowerCase(str.charAt(0)) + str.substring(1);
    }

3)swapCase方法

    /**
     * 大小写交换,即大写变小写,小写变大写
     *
     * @param str 要转换的字符串
     * @return 返回大小写字母转换后生成的新字符串
     */
    public static String swapCase(String str) {
        if (isEmpty(str)) {
            return str;
        } else {
            char[] charArray = str.toCharArray();
            for (int i = 0; i < charArray.length; i++) {
                if (Character.isUpperCase(charArray[i])) {
                    charArray[i] = Character.toLowerCase(charArray[i]);
                } else if (Character.isLowerCase(charArray[i])) {
                    charArray[i] = Character.toUpperCase(charArray[i]);
                }
            }
            return new String(charArray);
        }
    }

5.2 命名格式转换

1)camelCase方法

将下划线命名法的字符串转换为驼峰命名法(首字母小写)

    /**
     * 将下划线命名法的字符串转换为驼峰命名法(首字母小写)
     * 例如: "hello_world" -> "helloWorld"
     *
     * @param str 要转换的字符串
     * @return 转换后的字符串
     */
    public static String camelCase(String str) {
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        String[] words = str.split("_");
        sb.append(words[0]);
        for (int i = 1; i < words.length; i++) {
            sb.append(capitalize(words[i]));
        }
        return sb.toString();
    }

2)pascalCase方法

将下划线命名法的字符串转换为帕斯卡命名法(首字母大写)

    /**
     * 将下划线命名法的字符串转换为帕斯卡命名法(首字母大写)
     * 例如: "hello_world" -> "HelloWorld"
     *
     * @param str 要转换的字符串
     * @return 转换后的字符串
     */
    public static String pascalCase(String str) {
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        String[] words = str.split("_");
        for (int i = 0; i < words.length; i++) {
            sb.append(capitalize(words[i]));
        }
        return sb.toString();
    }

3)pascalCase方法

将字符串转换为下划线命名法(小写字母,单词间用下划线分隔)

    /**
     * 将字符串转换为下划线命名法(小写字母,单词间用下划线分隔)
     * 例如: "HelloWorld" -> "hello_world"
     *
     * @param str 要转换的字符串
     * @return 转换后的字符串
     */
    public static String snakeCase(String str) {
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (Character.isUpperCase(c)) {
                if (i > 0) {
                    sb.append('_');
                }
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

5.3 字符串缩略

1)abbreviate方法

将字符串缩减为指定宽度,注意,maxWidth必须>=4,否则抛异常;
如果字符长度小于maxWidth,直接返回该字符串,否则缩减效果为 substring(str, 0, max-3) + “…”

    /**
     * 将指定位置后面的字符串以省略号显示
     *
     * @param str
     * @param maxWidth
     * @return
     */
    public static String abbreviate(String str, int maxWidth) {
        return abbreviate(str, "...", 0, maxWidth);
    }

    /**
     * 指定偏移量,将指定位置后面的字符串以省略号显示
     *
     * @param str
     * @param offset
     * @param maxWidth
     * @return
     */
    public static String abbreviate(String str, int offset, int maxWidth) {
        return abbreviate(str, "...", offset, maxWidth);
    }

    /**
     * 将指定位置后面的字符串以指定字符显示
     *
     * @param str
     * @param abbrevMarker
     * @param maxWidth
     * @return
     */
    public static String abbreviate(String str, String abbrevMarker, int maxWidth) {
        return abbreviate(str, abbrevMarker, 0, maxWidth);
    }

    /**
     * 指定偏移量,将指定位置后面的字符串以指定字符显示
     *
     * @param str
     * @param abbrevMarker
     * @param offset
     * @param maxWidth
     * @return
     */
    public static String abbreviate(String str, String abbrevMarker, int offset, int maxWidth) {
        if (isNotEmpty(str) && "".equals(abbrevMarker) && maxWidth > 0) {
            return substring(str, 0, maxWidth);
        } else if (isEmpty(str) || isEmpty(abbrevMarker)) {
            return str;
        } else {
            int abbrevMarkerLength = abbrevMarker.length();
            int minAbbrevWidth = abbrevMarkerLength + 1;
            int minAbbrevWidthOffset = abbrevMarkerLength + abbrevMarkerLength + 1;
            if (maxWidth < minAbbrevWidth) {
                throw new IllegalArgumentException(String.format("Minimum abbreviation width is %d", minAbbrevWidth));
            } else {
                int strLen = str.length();
                if (strLen <= maxWidth) {
                    return str;
                } else {
                    if (offset > strLen) {
                        offset = strLen;
                    }
                    if (strLen - offset < maxWidth - abbrevMarkerLength) {
                        offset = strLen - (maxWidth - abbrevMarkerLength);
                    }
                    if (offset <= abbrevMarkerLength + 1) {
                        return str.substring(0, maxWidth - abbrevMarkerLength) + abbrevMarker;
                    } else if (maxWidth < minAbbrevWidthOffset) {
                        throw new IllegalArgumentException(String.format("Minimum abbreviation width with offset is %d", minAbbrevWidthOffset));
                    } else {
                        return offset + maxWidth - abbrevMarkerLength < strLen ? abbrevMarker + abbreviate(str.substring(offset), abbrevMarker, maxWidth - abbrevMarkerLength) : abbrevMarker + str.substring(strLen - (maxWidth - abbrevMarkerLength));
                    }
                }
            }
        }
    }

    /**
     * 字符串缩略
     *
     * @param str
     * @param middle
     * @param length
     * @return
     */
    public static String abbreviateMiddle(String str, String middle, int length) {
        if (isNotEmpty(str) && isNotEmpty(middle) && length < str.length() && length >= middle.length() + 2) {
            int targetSting = length - middle.length();
            int startOffset = targetSting / 2 + targetSting % 2;
            int endOffset = str.length() - targetSting / 2;
            return str.substring(0, startOffset) + middle + str.substring(endOffset);
        } else {
            return str;
        }
    }

5.4 补齐字符串

自动补齐至指定宽度,可指定字符,如不指定,默认补空格,有三个,center、leftPad和rightPad
使用场景:
        显示时补充数据宽度一致使其对齐,更美观
        单据流水号,宽度固定,左侧补0

1)leftPad方法

    /**
     * 左侧补齐,自动补齐至指定宽,使用空格补齐
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @return
     */
    public static String leftPad(String str, int size) {
        return leftPad(str, size, ' ');
    }

    /**
     * 左侧补齐,自动补齐至指定宽度,可指定字符
     *
     * @param str 原始字符串
     * @param size  字符串的长度
     * @param padChar  补充的字符
     * @return
     */
    public static String leftPad(String str, int size, char padChar) {
        if (str == null) {
            return null;
        } else {
            int pads = size - str.length();
            if (pads <= 0) {
                return str;
            } else {
                return pads > 8192 ? leftPad(str, size, String.valueOf(padChar)) : repeat(padChar, pads).concat(str);
            }
        }
    }

    /**
     * 左侧补齐,自动补齐至指定宽度,可指定字符
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @param padStr 补充的字符串
     * @return
     */
    public static String leftPad(String str, int size, String padStr) {
        if (str == null) {
            return null;
        } else {
            if (isEmpty(padStr)) {
                padStr = " ";
            }
            int padLen = padStr.length();
            int strLen = str.length();
            int pads = size - strLen;
            if (pads <= 0) {
                return str;
            } else if (padLen == 1 && pads <= 8192) {
                return leftPad(str, size, padStr.charAt(0));
            } else if (pads == padLen) {
                return padStr.concat(str);
            } else if (pads < padLen) {
                return padStr.substring(0, pads).concat(str);
            } else {
                char[] padding = new char[pads];
                char[] padChars = padStr.toCharArray();
                for(int i = 0; i < pads; ++i) {
                    padding[i] = padChars[i % padLen];
                }
                return (new String(padding)).concat(str);
            }
        }
    }

2)rightPad方法

    /**
     * 右侧补齐,自动补齐至指定宽,使用空格补齐
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @return
     */
    public static String rightPad(String str, int size) {
        return rightPad(str, size, ' ');
    }

    /**
     * 右侧补齐,自动补齐至指定宽度,可指定字符
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @param padChar 补充的字符
     * @return
     */
    public static String rightPad(String str, int size, char padChar) {
        if (str == null) {
            return null;
        } else {
            int pads = size - str.length();
            if (pads <= 0) {
                return str;
            } else {
                return pads > 8192 ? rightPad(str, size, String.valueOf(padChar)) : str.concat(repeat(padChar, pads));
            }
        }
    }

    /**
     * 右侧补齐,自动补齐至指定宽度,可指定字符
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @param padStr 补充的字符串
     * @return
     */
    public static String rightPad(String str, int size, String padStr) {
        if (str == null) {
            return null;
        } else {
            if (isEmpty(padStr)) {
                padStr = " ";
            }
            int padLen = padStr.length();
            int strLen = str.length();
            int pads = size - strLen;
            if (pads <= 0) {
                return str;
            } else if (padLen == 1 && pads <= 8192) {
                return rightPad(str, size, padStr.charAt(0));
            } else if (pads == padLen) {
                return str.concat(padStr);
            } else if (pads < padLen) {
                return str.concat(padStr.substring(0, pads));
            } else {
                char[] padding = new char[pads];
                char[] padChars = padStr.toCharArray();
                for(int i = 0; i < pads; ++i) {
                    padding[i] = padChars[i % padLen];
                }
                return str.concat(new String(padding));
            }
        }
    }

3)center方法

    /**
     * 中间填充
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @return
     */
    public static String center(String str, int size) {
        return center(str, size, ' ');
    }

    /**
     * 中间填充
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @param padChar 补充的字符
     * @return
     */
    public static String center(String str, int size, char padChar) {
        if (str != null && size > 0) {
            int strLen = str.length();
            int pads = size - strLen;
            if (pads <= 0) {
                return str;
            } else {
                str = leftPad(str, strLen + pads / 2, padChar);
                str = rightPad(str, size, padChar);
                return str;
            }
        } else {
            return str;
        }
    }

    /**
     * 中间填充
     *
     * @param str 原始字符串
     * @param size 字符串的长度
     * @param padStr 补充的字符串
     * @return
     */
    public static String center(String str, int size, String padStr) {
        if (str != null && size > 0) {
            if (isEmpty(padStr)) {
                padStr = " ";
            }

            int strLen = str.length();
            int pads = size - strLen;
            if (pads <= 0) {
                return str;
            } else {
                str = leftPad(str, strLen + pads / 2, padStr);
                str = rightPad(str, size, padStr);
                return str;
            }
        } else {
            return str;
        }
    }

5.5 旋转字符串

1)rotate方法

    /**
     * 旋转(循环移位)字符串
     *
     * @param str 原始字符串
     * @param shift 大于0则右旋,小于0则左旋
     * @return
     */
    public static String rotate(String str, int shift) {
        if (str == null) {
            return null;
        } else {
            int strLen = str.length();
            if (shift != 0 && strLen != 0 && shift % strLen != 0) {
                StringBuilder builder = new StringBuilder(strLen);
                int offset = -(shift % strLen);
                builder.append(substring(str, offset));
                builder.append(substring(str, 0, offset));
                return builder.toString();
            } else {
                return str;
            }
        }
    }

示例:

StringUtils.rotate("abcdefg", 2) = "fgabcde"
StringUtils.rotate("abcdefg", -2) = "cdefgab"

2)reverse方法

    /**
     * 将字符串反转,完全颠倒字符串顺序
     *
     * @param str 要反转的字符串
     * @return 反转后的字符串
     */
    public static String reverse(String str) {
        return str == null ? null : (new StringBuilder(str)).reverse().toString();
    }

3)reverseDelimited方法

    /**
     * 颠倒字符串顺序,以间隔符为单位进行,单个元素内部不颠倒位置
     *
     * @param str
     * @param separatorChar
     * @return
     */
    public static String reverseDelimited(String str, String separatorChar) {
        if (str == null) {
            return null;
        } else {
            String[] strs = split(str, separatorChar);
            //进行数组元素顺序反转
            if (strs != null) {
                int i = 0;
                for(int j = strs.length - 1; j > i; ++i) {
                    String tmp = strs[j];
                    strs[j] = strs[i];
                    strs[i] = tmp;
                    --j;
                }
            }
            return join((Object[])strs, separatorChar);
        }
    }

示例:

StringUtils.reverseDelimited("a.bc.d",'.')="d.bc.a"

5.6 编码转换

1)toEncodedString方法

将字节数组转换为指定编码的字符串。应用场景:系统间交互时,字符编码不一致,如对方传递的参数编码为GB2312,我方编码为UTF-8,可通过该方法进行转换。

    /**
     * 将字节数组转换为指定编码的字符串
     *
     * @param bytes
     * @param charset
     * @return
     */
    public static String toEncodedString(byte[] bytes, Charset charset) {
        charset = charset == null ? Charset.defaultCharset() : charset;
        return new String(bytes, charset);
    }

2)toCodePoints方法

将字节数组转换为Unicode代码点数组。

    /**
     * 将字符串转换为Unicode代码点数组
     *
     * @param cs
     * @return
     */
    public static int[] toCodePoints(CharSequence cs) {
        if (cs == null) {
            return null;
        } else if (cs.length() == 0) {
            return new int[0];
        } else {
            String s = cs.toString();
            int[] result = new int[s.codePointCount(0, s.length())];
            int index = 0;
            for(int i = 0; i < result.length; ++i) {
                result[i] = s.codePointAt(index);
                index += Character.charCount(result[i]);
            }
            return result;
        }
    }

6 文件路径名称相关

获取和操作文件路径,文件名和扩展名等

6.1 文件名

1)getFilename方法

    /**
     * 获取文件名
     *
     * @param path
     * @return
     */
    public static String getFilename(String path) {
        if (path == null) {
            return null;
        } else {
            int separatorIndex = path.lastIndexOf("/");
            return separatorIndex != -1 ? path.substring(separatorIndex + 1) : path;
        }
    }

6.2 文件扩展名

1)getFilenameExtension方法

    /**
     * 获取文件扩展名
     *
     * @param path
     * @return
     */
    public static String getFilenameExtension(String path) {
        if (path == null) {
            return null;
        } else {
            int extIndex = path.lastIndexOf(46);
            if (extIndex == -1) {
                return null;
            } else {
                int folderIndex = path.lastIndexOf("/");
                return folderIndex > extIndex ? null : path.substring(extIndex + 1);
            }
        }
    }

2)stripFilenameExtension方法

    /**
     * 舍去文件扩展名
     *
     * @param path
     * @return
     */
    public static String stripFilenameExtension(String path) {
        int extIndex = path.lastIndexOf(46);
        if (extIndex == -1) {
            return path;
        } else {
            int folderIndex = path.lastIndexOf("/");
            return folderIndex > extIndex ? path : path.substring(0, extIndex);
        }
    }

7 其他

难以归类的一些功能性方法

7.1 获取字符串长度

1)length方法

    /**
     * 获取字符串的长度
     *
     * @param str 要获取长度的字符串
     * @return 字符串的长度
     */
    public static int length(String str) {
        return str == null ? 0 : str.length();
    }

2)codePointCount方法

    /**
     * 获取字符串的长度(考虑Unicode扩展字符)
     *
     * @param str 要获取长度的字符串
     * @return 字符串的长度
     */
    public static int codePointCount(String str) {
        if (isEmpty(str)) {
            return 0;
        }
        return str.codePointCount(0, str.length());
    }

7.2.计算匹配次数

1)countMatches方法

    /**
     * 计算匹配次数
     *
     * @param str
     * @param ch
     * @return
     */
    public static int countMatches(String str, char ch) {
        if (isEmpty(str)) {
            return 0;
        } else {
            int count = 0;
            for(int i = 0; i < str.length(); ++i) {
                if (ch == str.charAt(i)) {
                    ++count;
                }
            }
            return count;
        }
    }

    /**
     * 计算匹配次数
     *
     * @param str
     * @param sub
     * @return
     */
    public static int countMatches(String str, String sub) {
        if (!isEmpty(str) && !isEmpty(sub)) {
            int count = 0;
            for(int idx = 0; (idx = indexOf(str, sub, idx)) != -1; idx += sub.length()) {
                ++count;
            }
            return count;
        } else {
            return 0;
        }
    }

7.3 默认值处理

1)defaultString方法

    /**
     * 获取默认字符串
     *
     * @param str
     * @return null及空格将会返回"",其他情况返回原始字符串
     */
    public static String defaultString(String str) {
        return defaultString(str, "");
    }

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

2)defaultIfBlank 和 defaultIfEmpty方法

    /**
     * 如果为空白,返回指定值
     *
     * @param str
     * @param defaultStr
     * @return
     */
    public static String defaultIfBlank(String str, String defaultStr) {
        return isBlank(str) ? defaultStr : str;
    }

    /**
     * 如果为空,返回指定值
     *
     * @param str
     * @param defaultStr
     * @return
     */
    public static String defaultIfEmpty(String str, String defaultStr) {
        return isEmpty(str) ? defaultStr : str;
    }

3)firstNonBlank 和 firstNonEmpty方法

    /**
     * 获取数组中第一个不为空白的元素
     *
     * @param values
     * @return
     */
    @SafeVarargs
    public static String firstNonBlank(String... values) {
        if (values != null) {
            String[] valArr = values;
            int len = values.length;
            for(int i = 0; i < len; ++i) {
                String val = valArr[i];
                if (isNotBlank(val)) {
                    return val;
                }
            }
        }
        return null;
    }

    /**
     * 获取数组中第一个不为空的元素
     *
     * @param values
     * @return
     */
    @SafeVarargs
    public static String firstNonEmpty(String... values) {
        if (values != null) {
            String[] valArr = values;
            int len = values.length;
            for(int i = 0; i < len; ++i) {
                String val = valArr[i];
                if (isNotEmpty(val)) {
                    return val;
                }
            }
        }
        return null;
    }

7.4.字符串差异

1)indexOfDifference方法

    /**
     * 获取字符串差异的索引位置
     *
     * @param str1
     * @param str2
     * @return
     */
    public static int indexOfDifference(String str1, String str2) {
        if (str1 == str2) {
            return -1;
        } else if (str1 != null && str2 != null) {
            int i;
            for(i = 0; i < str1.length() && i < str2.length() && str1.charAt(i) == str2.charAt(i); ++i) {
            }
            return i >= str2.length() && i >= str1.length() ? -1 : i;
        } else {
            return 0;
        }
    }

2)difference方法

    /**
     * 获取字符串差异部分
     *
     * @param str1
     * @param str2
     * @return
     */
    public static String difference(String str1, String str2) {
        if (str1 == null) {
            return str2;
        } else if (str2 == null) {
            return str1;
        } else {
            int at = indexOfDifference(str1, str2);
            return at == -1 ? "" : str2.substring(at);
        }
    }

7.5 取字符串相同前缀

1)getCommonPrefix方法

    /**
     * 获取字符串相同前缀
     *
     * @param str1
     * @param str2
     * @return
     */
    public static String getCommonPrefix(String str1, String str2) {
        if (isEmpty(str1) || isEmpty(str2)) {
            return "";
        } else {
            int smallestIndexOfDiff = indexOfDifference(str1, str2);
            if (smallestIndexOfDiff == -1) {
                return str1 == null ? "" : str1;
            } else {
                return smallestIndexOfDiff == 0 ? "" : str1.substring(0, smallestIndexOfDiff);
            }
        }
    }

示例:

StringUtils.getCommonPrefix(new String[] {"abcde", "abxyz"}) = "ab"

  • 21
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值