2018-11-14 java 字符串常用工具


/**
 * 字符串工具類
 *
 */
public class StrKit {

    public static final String SPACE = " ";
    public static final String DOT = ".";
    public static final String SLASH = "/";
    public static final String BACKSLASH = "\\";
    public static final String EMPTY = "";
    public static final String CRLF = "\r\n";
    public static final String NEWLINE = "\n";
    public static final String UNDERLINE = "_";
    public static final String COMMA = ",";

    public static final String HTML_NBSP = " ";
    public static final String HTML_AMP = "&amp";
    public static final String HTML_QUOTE = """;
    public static final String HTML_LT = "<";
    public static final String HTML_GT = ">";

    public static final String EMPTY_JSON = "{}";


    /**
     * 首字母變小寫
     */
    public static String firstCharToLowerCase(String str) {
        char firstChar = str.charAt(0);
        if (firstChar >= 'A' && firstChar <= 'Z') {
            char[] arr = str.toCharArray();
            arr[0] += ('a' - 'A');
            return new String(arr);
        }
        return str;
    }
    
    /**
     * 首字母變大寫
     */
    public static String firstCharToUpperCase(String str) {
        char firstChar = str.charAt(0);
        if (firstChar >= 'a' && firstChar <= 'z') {
            char[] arr = str.toCharArray();
            arr[0] -= ('a' - 'A');
            return new String(arr);
        }
        return str;
    }

    // ------------------------------------------------------------------------ Blank
    /**
     * 字符串是否為空白 空白的定義如下: <br>
     * 1、為null <br>
     * 2、為不可見字符(如空格)<br>
     * 3、""<br>
     * 
     * @param str 被檢測的字符串
     * @return 是否為空
     */
    public static boolean isBlank(String str) {
        int length;
        if ((str == null) || ((length = str.length()) == 0)) {
            return true;
        }
        for (int i = 0; i < length; i++) {
            // 只要有一個非空字符即為非空字符串
            if (false == Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 字符串是否為非空白 空白的定義如下: <br>
     * 1、不為null <br>
     * 2、不為不可見字符(如空格)<br>
     * 3、不為""<br>
     * 
     * @param str 被檢測的字符串
     * @return 是否為非空
     */
    public static boolean notBlank(String str) {
        return false == isBlank(str);
    }

    /**
     * 是否包含空字符串
     * 
     * @param strs 字符串列表
     * @return 是否包含空字符串
     */
    public static boolean hasBlank(String... strs) {
        if (CollectionKit.isEmpty(strs)) {
            return true;
        }
        for (String str : strs) {
            if (isBlank(str)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 給定所有字符串是否為空白
     * 
     * @param strs 字符串
     * @return 所有字符串是否為空白
     */
    public static boolean isAllBlank(String... strs) {
        if (CollectionKit.isEmpty(strs)) {
            return true;
        }
        for (String str : strs) {
            if (notBlank(str)) {
                return false;
            }
        }
        return true;
    }

    // ------------------------------------------------------------------------ Empty
    /**
     * 字符串是否為空,空的定義如下 1、為null <br>
     * 2、為""<br>
     * 
     * @param str 被檢測的字符串
     * @return 是否為空
     */
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    /**
     * 字符串是否為非空白 空白的定義如下: <br>
     * 1、不為null <br>
     * 2、不為""<br>
     * 
     * @param str 被檢測的字符串
     * @return 是否為非空
     */
    public static boolean isNotEmpty(String str) {
        return false == isEmpty(str);
    }

    /**
     * 當(dāng)給定字符串為null時,轉(zhuǎn)換為Empty
     * 
     * @param str 被轉(zhuǎn)換的字符串
     * @return 轉(zhuǎn)換后的字符串
     */
    public static String nullToEmpty(String str) {
        return nullToDefault(str, EMPTY);
    }

    /**
     * 如果字符串是<code>null</code>,則返回指定默認字符串,否則返回字符串本身。
     * 
     * <pre>
     * nullToDefault(null, &quot;default&quot;)  = &quot;default&quot;
     * nullToDefault(&quot;&quot;, &quot;default&quot;)    = &quot;&quot;
     * nullToDefault(&quot;  &quot;, &quot;default&quot;)  = &quot;  &quot;
     * nullToDefault(&quot;bat&quot;, &quot;default&quot;) = &quot;bat&quot;
     * </pre>
     * 
     * @param str 要轉(zhuǎn)換的字符串
     * @param defaultStr 默認字符串
     * 
     * @return 字符串本身或指定的默認字符串
     */
    public static String nullToDefault(String str, String defaultStr) {
        return (str == null) ? defaultStr : str;
    }

    /**
     * 當(dāng)給定字符串為空字符串時,轉(zhuǎn)換為<code>null</code>
     * 
     * @param str 被轉(zhuǎn)換的字符串
     * @return 轉(zhuǎn)換后的字符串
     */
    public static String emptyToNull(String str) {
        return isEmpty(str) ? null : str;
    }

    /**
     * 是否包含空字符串
     * 
     * @param strs 字符串列表
     * @return 是否包含空字符串
     */
    public static boolean hasEmpty(String... strs) {
        if (CollectionKit.isEmpty(strs)) {
            return true;
        }

        for (String str : strs) {
            if (isEmpty(str)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否全部為空字符串
     * 
     * @param strs 字符串列表
     * @return 是否全部為空字符串
     */
    public static boolean isAllEmpty(String... strs) {
        if (CollectionKit.isEmpty(strs)) {
            return true;
        }

        for (String str : strs) {
            if (isNotEmpty(str)) {
                return false;
            }
        }
        return true;
    }

    // ------------------------------------------------------------------------ Trim
    /**
     * 除去字符串頭尾部的空白,如果字符串是<code>null</code>,依然返回<code>null</code>。
     * 
     * <p>
     * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 來判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
     * 
     * <pre>
     * trim(null)          = null
     * trim(&quot;&quot;)            = &quot;&quot;
     * trim(&quot;     &quot;)       = &quot;&quot;
     * trim(&quot;abc&quot;)         = &quot;abc&quot;
     * trim(&quot;    abc    &quot;) = &quot;abc&quot;
     * </pre>
     * 
     * </p>
     * 
     * @param str 要處理的字符串
     * 
     * @return 除去空白的字符串,如果原字串為<code>null</code>,則返回<code>null</code>
     */
    public static String trim(String str) {
        return (null == str) ? null : trim(str, 0);
    }

    /**
     * 給定字符串?dāng)?shù)組全部做去首尾空格
     * 
     * @param strs 字符串?dāng)?shù)組
     */
    public static void trim(String[] strs) {
        if (null == strs) {
            return;
        }
        String str;
        for (int i = 0; i < strs.length; i++) {
            str = strs[i];
            if (null != str) {
                strs[i] = str.trim();
            }
        }
    }

    /**
     * 除去字符串頭部的空白,如果字符串是<code>null</code>,則返回<code>null</code>。
     * 
     * <p>
     * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 來判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
     * 
     * <pre>
     * trimStart(null)         = null
     * trimStart(&quot;&quot;)           = &quot;&quot;
     * trimStart(&quot;abc&quot;)        = &quot;abc&quot;
     * trimStart(&quot;  abc&quot;)      = &quot;abc&quot;
     * trimStart(&quot;abc  &quot;)      = &quot;abc  &quot;
     * trimStart(&quot; abc &quot;)      = &quot;abc &quot;
     * </pre>
     * 
     * </p>
     * 
     * @param str 要處理的字符串
     * 
     * @return 除去空白的字符串,如果原字串為<code>null</code>或結(jié)果字符串為<code>""</code>,則返回 <code>null</code>
     */
    public static String trimStart(String str) {
        return trim(str, -1);
    }

    /**
     * 除去字符串尾部的空白,如果字符串是<code>null</code>,則返回<code>null</code>。
     * 
     * <p>
     * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 來判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
     * 
     * <pre>
     * trimEnd(null)       = null
     * trimEnd(&quot;&quot;)         = &quot;&quot;
     * trimEnd(&quot;abc&quot;)      = &quot;abc&quot;
     * trimEnd(&quot;  abc&quot;)    = &quot;  abc&quot;
     * trimEnd(&quot;abc  &quot;)    = &quot;abc&quot;
     * trimEnd(&quot; abc &quot;)    = &quot; abc&quot;
     * </pre>
     * 
     * </p>
     * 
     * @param str 要處理的字符串
     * 
     * @return 除去空白的字符串,如果原字串為<code>null</code>或結(jié)果字符串為<code>""</code>,則返回 <code>null</code>
     */
    public static String trimEnd(String str) {
        return trim(str, 1);
    }

    /**
     * 除去字符串頭尾部的空白符,如果字符串是<code>null</code>,依然返回<code>null</code>。
     * 
     * @param str 要處理的字符串
     * @param mode <code>-1</code>表示trimStart,<code>0</code>表示trim全部, <code>1</code>表示trimEnd
     * 
     * @return 除去指定字符后的的字符串,如果原字串為<code>null</code>,則返回<code>null</code>
     */
    public static String trim(String str, int mode) {
        if (str == null) {
            return null;
        }

        int length = str.length();
        int start = 0;
        int end = length;

        // 掃描字符串頭部
        if (mode <= 0) {
            while ((start < end) && (Character.isWhitespace(str.charAt(start)))) {
                start++;
            }
        }

        // 掃描字符串尾部
        if (mode >= 0) {
            while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) {
                end--;
            }
        }

        if ((start > 0) || (end < length)) {
            return str.substring(start, end);
        }

        return str;
    }
    
    /**
     * 是否以指定字符串開頭
     * @param str 被監(jiān)測字符串
     * @param prefix 開頭字符串
     * @param isIgnoreCase 是否忽略大小寫
     * @return 是否以指定字符串開頭
     */
    public static boolean startWith(String str, String prefix, boolean isIgnoreCase){
        if(isIgnoreCase){
            return str.toLowerCase().startsWith(prefix.toLowerCase());
        }else{
            return str.startsWith(prefix);
        }
    }
    
    /**
     * 是否以指定字符串結(jié)尾
     * @param str 被監(jiān)測字符串
     * @param suffix 結(jié)尾字符串
     * @param isIgnoreCase 是否忽略大小寫
     * @return 是否以指定字符串結(jié)尾
     */
    public static boolean endWith(String str, String suffix, boolean isIgnoreCase){
        if(isIgnoreCase){
            return str.toLowerCase().endsWith(suffix.toLowerCase());
        }else{
            return str.endsWith(suffix);
        }
    }
    
    /**
     * 是否包含特定字符,忽略大小寫,如果給定兩個參數(shù)都為<code>null</code>,返回true
     * @param str 被檢測字符串
     * @param testStr 被測試是否包含的字符串
     * @return 是否包含
     */
    public static boolean containsIgnoreCase(String str, String testStr){
        if(null == str){
            //如果被監(jiān)測字符串和 
            return null == testStr;
        }
        return str.toLowerCase().contains(testStr.toLowerCase());
    }

    /**
     * 獲得set或get方法對應(yīng)的標(biāo)準(zhǔn)屬性名<br/>
     * 例如:setName 返回 name
     * 
     * @param getOrSetMethodName
     * @return 如果是set或get方法名,返回field, 否則null
     */
    public static String getGeneralField(String getOrSetMethodName) {
        if (getOrSetMethodName.startsWith("get") || getOrSetMethodName.startsWith("set")) {
            return cutPreAndLowerFirst(getOrSetMethodName, 3);
        }
        return null;
    }

    /**
     * 生成set方法名<br/>
     * 例如:name 返回 setName
     * 
     * @param fieldName 屬性名
     * @return setXxx
     */
    public static String genSetter(String fieldName) {
        return upperFirstAndAddPre(fieldName, "set");
    }

    /**
     * 生成get方法名
     * 
     * @param fieldName 屬性名
     * @return getXxx
     */
    public static String genGetter(String fieldName) {
        return upperFirstAndAddPre(fieldName, "get");
    }

    /**
     * 去掉首部指定長度的字符串并將剩余字符串首字母小寫<br/>
     * 例如:str=setName, preLength=3 -> return name
     * 
     * @param str 被處理的字符串
     * @param preLength 去掉的長度
     * @return 處理后的字符串,不符合規(guī)范返回null
     */
    public static String cutPreAndLowerFirst(String str, int preLength) {
        if (str == null) {
            return null;
        }
        if (str.length() > preLength) {
            char first = Character.toLowerCase(str.charAt(preLength));
            if (str.length() > preLength + 1) {
                return first + str.substring(preLength + 1);
            }
            return String.valueOf(first);
        }
        return null;
    }

    /**
     * 原字符串首字母大寫并在其首部添加指定字符串 例如:str=name, preString=get -> return getName
     * 
     * @param str 被處理的字符串
     * @param preString 添加的首部
     * @return 處理后的字符串
     */
    public static String upperFirstAndAddPre(String str, String preString) {
        if (str == null || preString == null) {
            return null;
        }
        return preString + upperFirst(str);
    }

    /**
     * 大寫首字母<br>
     * 例如:str = name, return Name
     * 
     * @param str 字符串
     * @return 字符串
     */
    public static String upperFirst(String str) {
        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
    }

    /**
     * 小寫首字母<br>
     * 例如:str = Name, return name
     * 
     * @param str 字符串
     * @return 字符串
     */
    public static String lowerFirst(String str) {
        if(isBlank(str)){
            return str;
        }
        return Character.toLowerCase(str.charAt(0)) + str.substring(1);
    }

    /**
     * 去掉指定前綴
     * 
     * @param str 字符串
     * @param prefix 前綴
     * @return 切掉后的字符串,若前綴不是 preffix, 返回原字符串
     */
    public static String removePrefix(String str, String prefix) {
        if(isEmpty(str) || isEmpty(prefix)){
            return str;
        }
        
        if (str.startsWith(prefix)) {
            return str.substring(prefix.length());
        }
        return str;
    }

    /**
     * 忽略大小寫去掉指定前綴
     * 
     * @param str 字符串
     * @param prefix 前綴
     * @return 切掉后的字符串,若前綴不是 prefix, 返回原字符串
     */
    public static String removePrefixIgnoreCase(String str, String prefix) {
        if(isEmpty(str) || isEmpty(prefix)){
            return str;
        }
        
        if (str.toLowerCase().startsWith(prefix.toLowerCase())) {
            return str.substring(prefix.length());
        }
        return str;
    }

    /**
     * 去掉指定后綴
     * 
     * @param str 字符串
     * @param suffix 后綴
     * @return 切掉后的字符串,若后綴不是 suffix, 返回原字符串
     */
    public static String removeSuffix(String str, String suffix) {
        if(isEmpty(str) || isEmpty(suffix)){
            return str;
        }
        
        if (str.endsWith(suffix)) {
            return str.substring(0, str.length() - suffix.length());
        }
        return str;
    }
    
    /**
     * 獲得字符串對應(yīng)byte數(shù)組
     * @param str 字符串
     * @param charset 編碼,如果為<code>null</code>使用系統(tǒng)默認編碼
     * @return bytes
     */
    public static byte[] getBytes(String str, Charset charset){
        if(null == str){
            return null;
        }
        return null == charset ? str.getBytes() : str.getBytes(charset);
    }

    /**
     * 忽略大小寫去掉指定后綴
     * 
     * @param str 字符串
     * @param suffix 后綴
     * @return 切掉后的字符串,若后綴不是 suffix, 返回原字符串
     */
    public static String removeSuffixIgnoreCase(String str, String suffix) {
        if(isEmpty(str) || isEmpty(suffix)){
            return str;
        }
        
        if (str.toLowerCase().endsWith(suffix.toLowerCase())) {
            return str.substring(0, str.length() - suffix.length());
        }
        return str;
    }
    
    /**
     * 如果給定字符串不是以prefix開頭的,在開頭補充 prefix
     * @param str 字符串
     * @param prefix 前綴
     * @return 補充后的字符串
     */
    public static String addPrefixIfNot(String str, String prefix){
        if(isEmpty(str) || isEmpty(prefix)){
            return str;
        }
        if(false == str.startsWith(prefix)){
            str = prefix + str;
        }
        return str;
    }
    
    /**
     * 如果給定字符串不是以suffix結(jié)尾的,在尾部補充 suffix
     * @param str 字符串
     * @param suffix 后綴
     * @return 補充后的字符串
     */
    public static String addSuffixIfNot(String str, String suffix){
        if(isEmpty(str) || isEmpty(suffix)){
            return str;
        }
        if(false == str.endsWith(suffix)){
            str += suffix;
        }
        return str;
    }

    /**
     * 清理空白字符
     * 
     * @param str 被清理的字符串
     * @return 清理后的字符串
     */
    public static String cleanBlank(String str) {
        if (str == null) {
            return null;
        }

        return str.replaceAll("\\s*", EMPTY);
    }

    /**
     * 切分字符串<br>
     * a#b#c -> [a,b,c] <br>
     * a##b#c -> [a,"",b,c]
     * 
     * @param str 被切分的字符串
     * @param separator 分隔符字符
     * @return 切分后的集合
     */
    public static List<String> split(String str, char separator) {
        return split(str, separator, 0);
    }

    /**
     * 切分字符串
     * 
     * @param str 被切分的字符串
     * @param separator 分隔符字符
     * @param limit 限制分片數(shù)
     * @return 切分后的集合
     */
    public static List<String> split(String str, char separator, int limit) {
        if (str == null) {
            return null;
        }
        List<String> list = new ArrayList<String>(limit == 0 ? 16 : limit);
        if (limit == 1) {
            list.add(str);
            return list;
        }

        boolean isNotEnd = true; // 未結(jié)束切分的標(biāo)志
        int strLen = str.length();
        StringBuilder sb = new StringBuilder(strLen);
        for (int i = 0; i < strLen; i++) {
            char c = str.charAt(i);
            if (isNotEnd && c == separator) {
                list.add(sb.toString());
                // 清空StringBuilder
                sb.delete(0, sb.length());

                // 當(dāng)達到切分上限-1的量時,將所剩字符全部作為最后一個串
                if (limit != 0 && list.size() == limit - 1) {
                    isNotEnd = false;
                }
            } else {
                sb.append(c);
            }
        }
        list.add(sb.toString());// 加入尾串
        return list;
    }

    /**
     * 切分字符串<br>
     * from jodd
     * 
     * @param str 被切分的字符串
     * @param delimiter 分隔符
     * @return 字符串
     */
    public static String[] split(String str, String delimiter) {
        if (str == null) {
            return null;
        }
        if (str.trim().length() == 0) {
            return new String[] { str };
        }

        int dellen = delimiter.length(); // del length
        int maxparts = (str.length() / dellen) + 2; // one more for the last
        int[] positions = new int[maxparts];

        int i, j = 0;
        int count = 0;
        positions[0] = -dellen;
        while ((i = str.indexOf(delimiter, j)) != -1) {
            count++;
            positions[count] = i;
            j = i + dellen;
        }
        count++;
        positions[count] = str.length();

        String[] result = new String[count];

        for (i = 0; i < count; i++) {
            result[i] = str.substring(positions[i] + dellen, positions[i + 1]);
        }
        return result;
    }

    /**
     * 改進JDK subString<br>
     * index從0開始計算,最后一個字符為-1<br>
     * 如果from和to位置一樣,返回 "" <br>
     * 如果from或to為負數(shù),則按照length從后向前數(shù)位置,如果絕對值大于字符串長度,則from歸到0,to歸到length<br>
     * 如果經(jīng)過修正的index中from大于to,則互換from和to
     * example: <br>
     *  abcdefgh 2 3 -> c <br>
     *  abcdefgh 2 -3 -> cde <br>
     * 
     * @param string String
     * @param fromIndex 開始的index(包括)
     * @param toIndex 結(jié)束的index(不包括)
     * @return 字串
     */
    public static String sub(String string, int fromIndex, int toIndex) {
        int len = string.length();
        if (fromIndex < 0) {
            fromIndex = len + fromIndex;
            if(fromIndex < 0 ) { 
                fromIndex = 0;
            }
        } else if(fromIndex >= len) {
            fromIndex = len -1;
        }
        if (toIndex < 0) {
            toIndex = len + toIndex;
            if(toIndex < 0) {
                toIndex = len;
            }
        } else if(toIndex > len) {
            toIndex = len;
        }
        if (toIndex < fromIndex) {
            int tmp = fromIndex;
            fromIndex = toIndex;
            toIndex = tmp;
        }
        if (fromIndex == toIndex) {
            return EMPTY;
        }
        char[] strArray = string.toCharArray();
        char[] newStrArray = Arrays.copyOfRange(strArray, fromIndex, toIndex);
        return new String(newStrArray);
    }

    /**
     * 切割前部分
     * 
     * @param string 字符串
     * @param toIndex 切割到的位置(不包括)
     * @return 切割后的字符串
     */
    public static String subPre(String string, int toIndex) {
        return sub(string, 0, toIndex);
    }

    /**
     * 切割后部分
     * 
     * @param string 字符串
     * @param fromIndex 切割開始的位置(包括)
     * @return 切割后的字符串
     */
    public static String subSuf(String string, int fromIndex) {
        if (isEmpty(string)) {
            return null;
        }
        return sub(string, fromIndex, string.length());
    }

    /**
     * 給定字符串是否被字符包圍
     * 
     * @param str 字符串
     * @param prefix 前綴
     * @param suffix 后綴
     * @return 是否包圍,空串不包圍
     */
    public static boolean isSurround(String str, String prefix, String suffix) {
        if (StrKit.isBlank(str)) {
            return false;
        }
        if (str.length() < (prefix.length() + suffix.length())) {
            return false;
        }

        return str.startsWith(prefix) && str.endsWith(suffix);
    }

    /**
     * 給定字符串是否被字符包圍
     * 
     * @param str 字符串
     * @param prefix 前綴
     * @param suffix 后綴
     * @return 是否包圍,空串不包圍
     */
    public static boolean isSurround(String str, char prefix, char suffix) {
        if (StrKit.isBlank(str)) {
            return false;
        }
        if (str.length() < 2) {
            return false;
        }

        return str.charAt(0) == prefix && str.charAt(str.length() - 1) == suffix;
    }

    /**
     * 重復(fù)某個字符
     * 
     * @param c 被重復(fù)的字符
     * @param count 重復(fù)的數(shù)目
     * @return 重復(fù)字符字符串
     */
    public static String repeat(char c, int count) {
        char[] result = new char[count];
        for (int i = 0; i < count; i++) {
            result[i] = c;
        }
        return new String(result);
    }

    /**
     * 重復(fù)某個字符串
     * 
     * @param str 被重復(fù)的字符
     * @param count 重復(fù)的數(shù)目
     * @return 重復(fù)字符字符串
     */
    public static String repeat(String str, int count) {

        // 檢查
        final int len = str.length();
        final long longSize = (long) len * (long) count;
        final int size = (int) longSize;
        if (size != longSize) {
            throw new ArrayIndexOutOfBoundsException("Required String length is too large: " + longSize);
        }

        final char[] array = new char[size];
        str.getChars(0, len, array, 0);
        int n;
        for (n = len; n < size - n; n <<= 1) {// n <<= 1相當(dāng)于n *2
            System.arraycopy(array, 0, array, n, n);
        }
        System.arraycopy(array, 0, array, n, size - n);
        return new String(array);
    }

    /**
     * 比較兩個字符串(大小寫敏感)。
     * 
     * <pre>
     * equals(null, null)   = true
     * equals(null, &quot;abc&quot;)  = false
     * equals(&quot;abc&quot;, null)  = false
     * equals(&quot;abc&quot;, &quot;abc&quot;) = true
     * equals(&quot;abc&quot;, &quot;ABC&quot;) = false
     * </pre>
     * 
     * @param str1 要比較的字符串1
     * @param str2 要比較的字符串2
     * 
     * @return 如果兩個字符串相同,或者都是<code>null</code>,則返回<code>true</code>
     */
    public static boolean equals(String str1, String str2) {
        if (str1 == null) {
            return str2 == null;
        }

        return str1.equals(str2);
    }

    /**
     * 比較兩個字符串(大小寫不敏感)。
     * 
     * <pre>
     * equalsIgnoreCase(null, null)   = true
     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
     * </pre>
     * 
     * @param str1 要比較的字符串1
     * @param str2 要比較的字符串2
     * 
     * @return 如果兩個字符串相同,或者都是<code>null</code>,則返回<code>true</code>
     */
    public static boolean equalsIgnoreCase(String str1, String str2) {
        if (str1 == null) {
            return str2 == null;
        }

        return str1.equalsIgnoreCase(str2);
    }

    /**
     * 格式化文本, {} 表示占位符<br>
     * 例如:format("aaa {} ccc", "bbb")   ---->    aaa bbb ccc
     * 
     * @param template 文本模板,被替換的部分用 {} 表示
     * @param values 參數(shù)值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... values) {
        if (CollectionKit.isEmpty(values) || isBlank(template)) {
            return template;
        }

        final StringBuilder sb = new StringBuilder();
        final int length = template.length();

        int valueIndex = 0;
        char currentChar;
        for (int i = 0; i < length; i++) {
            if (valueIndex >= values.length) {
                sb.append(sub(template, i, length));
                break;
            }

            currentChar = template.charAt(i);
            if (currentChar == '{') {
                final char nextChar = template.charAt(++i);
                if (nextChar == '}') {
                    sb.append(values[valueIndex++]);
                } else {
                    sb.append('{').append(nextChar);
                }
            } else {
                sb.append(currentChar);
            }

        }

        return sb.toString();
    }

    /**
     * 格式化文本,使用 {varName} 占位<br>
     * map = {a: "aValue", b: "bValue"}
     * format("{a} and ", map)    ---->    aValue and bValue
     * 
     * @param template 文本模板,被替換的部分用 {key} 表示
     * @param map 參數(shù)值對
     * @return 格式化后的文本
     */
    public static String format(String template, Map<?, ?> map) {
        if (null == map || map.isEmpty()) {
            return template;
        }

        for (Entry<?, ?> entry : map.entrySet()) {
            template = template.replace("{" + entry.getKey() + "}", entry.getValue().toString());
        }
        return template;
    }
    
    /**
     * 編碼字符串
     * 
     * @param str 字符串
     * @param charset 字符集,如果此字段為空,則解碼的結(jié)果取決于平臺
     * @return 編碼后的字節(jié)碼
     */
    public static byte[] bytes(String str, String charset) {
        return bytes(str, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset));
    }

    /**
     * 編碼字符串
     * 
     * @param str 字符串
     * @param charset 字符集,如果此字段為空,則解碼的結(jié)果取決于平臺
     * @return 編碼后的字節(jié)碼
     */
    public static byte[] bytes(String str, Charset charset) {
        if (str == null) {
            return null;
        }

        if (null == charset) {
            return str.getBytes();
        }
        return str.getBytes(charset);
    }
    
    /**
     * 將byte數(shù)組轉(zhuǎn)為字符串
     * 
     * @param bytes byte數(shù)組
     * @param charset 字符集
     * @return 字符串
     */
    public static String str(byte[] bytes, String charset) {
        return str(bytes, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset));
    }

    /**
     * 解碼字節(jié)碼
     * 
     * @param data 字符串
     * @param charset 字符集,如果此字段為空,則解碼的結(jié)果取決于平臺
     * @return 解碼后的字符串
     */
    public static String str(byte[] data, Charset charset) {
        if (data == null) {
            return null;
        }

        if (null == charset) {
            return new String(data);
        }
        return new String(data, charset);
    }
    
    /**
     * 將編碼的byteBuffer數(shù)據(jù)轉(zhuǎn)換為字符串
     * @param data 數(shù)據(jù)
     * @param charset 字符集,如果為空使用當(dāng)前系統(tǒng)字符集
     * @return 字符串
     */
    public static String str(ByteBuffer data, String charset){
        if(data == null) {
            return null;
        }
        
        return str(data, Charset.forName(charset));
    }
    
    /**
     * 將編碼的byteBuffer數(shù)據(jù)轉(zhuǎn)換為字符串
     * @param data 數(shù)據(jù)
     * @param charset 字符集,如果為空使用當(dāng)前系統(tǒng)字符集
     * @return 字符串
     */
    public static String str(ByteBuffer data, Charset charset){
        if(null == charset) {
            charset = Charset.defaultCharset();
        }
        return charset.decode(data).toString();
    }
    
    /**
     * 字符串轉(zhuǎn)換為byteBuffer
     * @param str 字符串
     * @param charset 編碼
     * @return byteBuffer
     */
    public static ByteBuffer byteBuffer(String str, String charset) {
        return ByteBuffer.wrap(StrKit.bytes(str, charset));
    }

    /**
     * 以 conjunction 為分隔符將多個對象轉(zhuǎn)換為字符串
     * 
     * @param conjunction 分隔符
     * @param objs 數(shù)組
     * @return 連接后的字符串
     */
    public static String join(String conjunction, Object... objs) {
        StringBuilder sb = new StringBuilder();
        boolean isFirst = true;
        for (Object item : objs) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append(conjunction);
            }
            sb.append(item);
        }
        return sb.toString();
    }
    
    /**
     * 將駝峰式命名的字符串轉(zhuǎn)換為下劃線方式。如果轉(zhuǎn)換前的駝峰式命名的字符串為空,則返回空字符串。</br>
     * 例如:HelloWorld->hello_world
     *
     * @param camelCaseStr 轉(zhuǎn)換前的駝峰式命名的字符串
     * @return 轉(zhuǎn)換后下劃線大寫方式命名的字符串
     */
    public static String toUnderlineCase(String camelCaseStr) {
        if (camelCaseStr == null) {
            return null;
        }

        final int length = camelCaseStr.length();
        StringBuilder sb = new StringBuilder();
        char c;
        boolean isPreUpperCase = false;
        for (int i = 0; i < length; i++) {
            c = camelCaseStr.charAt(i);
            boolean isNextUpperCase = true;
            if (i < (length - 1)) {
                isNextUpperCase = Character.isUpperCase(camelCaseStr.charAt(i + 1));
            }
            if (Character.isUpperCase(c)) {
                if (!isPreUpperCase || !isNextUpperCase) {
                    if (i > 0) sb.append(UNDERLINE);
                }
                isPreUpperCase = true;
            } else {
                isPreUpperCase = false;
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 將下劃線方式命名的字符串轉(zhuǎn)換為駝峰式。如果轉(zhuǎn)換前的下劃線大寫方式命名的字符串為空,則返回空字符串。</br>
     * 例如:hello_world->HelloWorld
     *
     * @param name 轉(zhuǎn)換前的下劃線大寫方式命名的字符串
     * @return 轉(zhuǎn)換后的駝峰式命名的字符串
     */
    public static String toCamelCase(String name) {
        if (name == null) {
            return null;
        }
        if (name.contains(UNDERLINE)) {
            name = name.toLowerCase();

            StringBuilder sb = new StringBuilder(name.length());
            boolean upperCase = false;
            for (int i = 0; i < name.length(); i++) {
                char c = name.charAt(i);

                if (c == '_') {
                    upperCase = true;
                } else if (upperCase) {
                    sb.append(Character.toUpperCase(c));
                    upperCase = false;
                } else {
                    sb.append(c);
                }
            }
            return sb.toString();
        } else
            return name;
    }

    /**
     * 包裝指定字符串
     * 
     * @param str 被包裝的字符串
     * @param prefix 前綴
     * @param suffix 后綴
     * @return 包裝后的字符串
     */
    public static String wrap(String str, String prefix, String suffix) {
        return format("{}{}{}", prefix, str, suffix);
    }

    /**
     * 指定字符串是否被包裝
     * 
     * @param str 字符串
     * @param prefix 前綴
     * @param suffix 后綴
     * @return 是否被包裝
     */
    public static boolean isWrap(String str, String prefix, String suffix) {
        return str.startsWith(prefix) && str.endsWith(suffix);
    }

    /**
     * 指定字符串是否被同一字符包裝(前后都有這些字符串)
     * 
     * @param str 字符串
     * @param wrapper 包裝字符串
     * @return 是否被包裝
     */
    public static boolean isWrap(String str, String wrapper) {
        return isWrap(str, wrapper, wrapper);
    }

    /**
     * 指定字符串是否被同一字符包裝(前后都有這些字符串)
     * 
     * @param str 字符串
     * @param wrapper 包裝字符
     * @return 是否被包裝
     */
    public static boolean isWrap(String str, char wrapper) {
        return isWrap(str, wrapper, wrapper);
    }

    /**
     * 指定字符串是否被包裝
     * 
     * @param str 字符串
     * @param prefixChar 前綴
     * @param suffixChar 后綴
     * @return 是否被包裝
     */
    public static boolean isWrap(String str, char prefixChar, char suffixChar) {
        return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar;
    }

    /**
     * 補充字符串以滿足最小長度 StrUtil.padPre("1", 3, '0');//"001"
     * 
     * @param str 字符串
     * @param minLength 最小長度
     * @param padChar 補充的字符
     * @return 補充后的字符串
     */
    public static String padPre(String str, int minLength, char padChar) {
        if (str.length() >= minLength) {
            return str;
        }
        StringBuilder sb = new StringBuilder(minLength);
        for (int i = str.length(); i < minLength; i++) {
            sb.append(padChar);
        }
        sb.append(str);
        return sb.toString();
    }

    /**
     * 補充字符串以滿足最小長度 StrUtil.padEnd("1", 3, '0');//"100"
     * 
     * @param str 字符串
     * @param minLength 最小長度
     * @param padChar 補充的字符
     * @return 補充后的字符串
     */
    public static String padEnd(String str, int minLength, char padChar) {
        if (str.length() >= minLength) {
            return str;
        }
        StringBuilder sb = new StringBuilder(minLength);
        sb.append(str);
        for (int i = str.length(); i < minLength; i++) {
            sb.append(padChar);
        }
        return sb.toString();
    }

    /**
     * 創(chuàng)建StringBuilder對象
     * 
     * @return StringBuilder對象
     */
    public static StringBuilder builder() {
        return new StringBuilder();
    }

    /**
     * 創(chuàng)建StringBuilder對象
     * 
     * @return StringBuilder對象
     */
    public static StringBuilder builder(int capacity) {
        return new StringBuilder(capacity);
    }

    /**
     * 創(chuàng)建StringBuilder對象
     * 
     * @return StringBuilder對象
     */
    public static StringBuilder builder(String... strs) {
        final StringBuilder sb = new StringBuilder();
        for (String str : strs) {
            sb.append(str);
        }
        return sb;
    }

    /**
     * 獲得StringReader
     * 
     * @param str 字符串
     * @return StringReader
     */
    public static StringReader getReader(String str) {
        return new StringReader(str);
    }

    /**
     * 獲得StringWriter
     * 
     * @return StringWriter
     */
    public static StringWriter getWriter() {
        return new StringWriter();
    }

        /**
     * 編碼字符串
     * 
     * @param str 字符串
     * @param charset 字符集,如果此字段為空,則解碼的結(jié)果取決于平臺
     * @return 編碼后的字節(jié)碼
     */
    public static byte[] encode(String str, String charset) {
        if (str == null) {
            return null;
        }

        if(isBlank(charset)) {
            return str.getBytes();
        }
        try {
            return str.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(format("Charset [{}] unsupported!", charset));
        }
    }

    /**
     * 解碼字節(jié)碼
     * 
     * @param data 字符串
     * @param charset 字符集,如果此字段為空,則解碼的結(jié)果取決于平臺
     * @return 解碼后的字符串
     */
    public static String decode(byte[] data, String charset) {
        if (data == null) {
            return null;
        }

        if(isBlank(charset)) {
            return new String(data);
        }
        try {
            return new String(data, charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(format("Charset [{}] unsupported!", charset));
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容