New file |
| | |
| | | package com.moral.api.utils; |
| | | |
| | | |
| | | import java.io.StringReader; |
| | | import java.io.StringWriter; |
| | | import java.io.UnsupportedEncodingException; |
| | | import java.nio.ByteBuffer; |
| | | import java.nio.charset.Charset; |
| | | import java.util.Arrays; |
| | | import java.util.Map; |
| | | import java.util.regex.Matcher; |
| | | import java.util.regex.Pattern; |
| | | |
| | | /*** |
| | | * @Author JI |
| | | * @Date 2020/3/27 13:44 |
| | | * @Param |
| | | * @return |
| | | **/ |
| | | public class StringUtils extends org.apache.commons.lang3.StringUtils { |
| | | |
| | | public static final String SPACE = " "; |
| | | public static final String DOT = "."; |
| | | public static final String PERIOD = "。"; |
| | | 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 COMMA_CN = ","; |
| | | public static final String CONNECTION_LINE = "-"; |
| | | public static final String SEMICOLON = ";"; |
| | | public static final String SEMICOLON_CN = ";"; |
| | | |
| | | public static final String HTML_NBSP = " "; |
| | | public static final String HTML_AMP = "&"; |
| | | public static final String HTML_QUOTE = """; |
| | | public static final String HTML_LT = "<"; |
| | | public static final String HTML_GT = ">"; |
| | | public static final String PLACEHOLDER = "%s"; |
| | | public static final String FILE_SEPARATOR = System.getProperties().getProperty("file.separator"); |
| | | public static final String EMPTY_JSON = "{}"; |
| | | |
| | | |
| | | /*** |
| | | * @Author JI |
| | | * @Description //判断是否为空(空格算空) |
| | | * @Date 2020/3/27 13:55 |
| | | * @Param [str] |
| | | * @return boolean |
| | | **/ |
| | | public static boolean isEmpty(String str) { |
| | | return str == null || "".equals(str.trim()) || "null".equals(str.trim()); |
| | | } |
| | | |
| | | public static boolean isBlank(Map param, String str) { |
| | | return !param.containsKey(str) || param.get(str) == null || "".equals(param.get(str).toString().trim()) || "null".equals(param.get(str).toString().trim()); |
| | | } |
| | | |
| | | public static boolean isNotBlank(Map param, String str) { |
| | | return !isBlank(param, str); |
| | | } |
| | | |
| | | /*** |
| | | * @Author JI |
| | | * @Description //判断是否为不为空(空格算空) |
| | | * @Date 2020/3/27 13:55 |
| | | * @Param [str] |
| | | * @return boolean |
| | | **/ |
| | | public static boolean isNotEmpty(String str) { |
| | | return !isEmpty(str); |
| | | } |
| | | |
| | | /** |
| | | * <p>Checks if a CharSequence is empty (""), null or whitespace only.</p> |
| | | * |
| | | * <p>Whitespace is defined by {@link Character#isWhitespace(char)}.</p> |
| | | * |
| | | * <pre> |
| | | * StringUtils.isBlank(null) = true |
| | | * StringUtils.isBlank("") = true |
| | | * StringUtils.isBlank(" ") = true |
| | | * StringUtils.isBlank("bob") = false |
| | | * StringUtils.isBlank(" bob ") = false |
| | | * </pre> |
| | | * |
| | | * @param cs the CharSequence to check, may be null |
| | | * @return {@code true} if the CharSequence is null, empty or whitespace only |
| | | * @since 2.0 |
| | | * @since 3.0 Changed signature from isBlank(String) to isBlank(CharSequence) |
| | | */ |
| | | public static boolean isBlank(final CharSequence cs) { |
| | | int strLen; |
| | | if (cs == null || (strLen = cs.length()) == 0) { |
| | | return true; |
| | | } |
| | | for (int i = 0; i < strLen; i++) { |
| | | if (!Character.isWhitespace(cs.charAt(i))) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 如果字符串是<code>null</code>,则返回指定默认字符串,否则返回字符串本身。 |
| | | * <p> |
| | | * <pre> |
| | | * nullToDefault(null, "default") = "default" |
| | | * nullToDefault("", "default") = "" |
| | | * nullToDefault(" ", "default") = " " |
| | | * nullToDefault("bat", "default") = "bat" |
| | | * </pre> |
| | | * |
| | | * @param str 要转换的字符串 |
| | | * @param defaultStr 默认字符串 |
| | | * @return 字符串本身或指定的默认字符串 |
| | | */ |
| | | public static String nullToDefault(String str, String defaultStr) { |
| | | return (str == null) ? defaultStr : str; |
| | | } |
| | | |
| | | /** |
| | | * 当给定字符串为空字符串时,转换为<code>null</code> |
| | | * |
| | | * @param str 被转换的字符串 |
| | | * @return 转换后的字符串 |
| | | */ |
| | | public static String emptyToNull(String str) { |
| | | return isEmpty(str) ? null : str; |
| | | } |
| | | |
| | | /** |
| | | * 是否包含空字符串 |
| | | * |
| | | * @param strs 字符串列表 |
| | | * @return 是否包含空字符串 |
| | | */ |
| | | public static boolean hasEmpty(String... strs) { |
| | | for (String str : strs) { |
| | | if (isEmpty(str)) { |
| | | return true; |
| | | } |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * 是否全部为空字符串 |
| | | * |
| | | * @param strs 字符串列表 |
| | | * @return 是否全部为空字符串 |
| | | */ |
| | | public static boolean isAllEmpty(String... strs) { |
| | | |
| | | for (String str : strs) { |
| | | if (isNotEmpty(str)) { |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | | /** |
| | | * 是否以指定字符串开头 |
| | | * |
| | | * @param str 被监测字符串 |
| | | * @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); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 是否以指定字符串结尾 |
| | | * |
| | | * @param str 被监测字符串 |
| | | * @param suffix 结尾字符串 |
| | | * @param isIgnoreCase 是否忽略大小写 |
| | | * @return 是否以指定字符串结尾 |
| | | */ |
| | | public static boolean endWith(String str, String suffix, boolean isIgnoreCase) { |
| | | if (isIgnoreCase) { |
| | | return str.toLowerCase().endsWith(suffix.toLowerCase()); |
| | | } else { |
| | | return str.endsWith(suffix); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 是否包含特定字符,忽略大小写,如果给定两个参数都为<code>null</code>,返回true |
| | | * |
| | | * @param str 被检测字符串 |
| | | * @param testStr 被测试是否包含的字符串 |
| | | * @return 是否包含 |
| | | */ |
| | | public static boolean containsIgnoreCase(String str, String testStr) { |
| | | if (null == str) { |
| | | //如果被监测字符串和 |
| | | return null == testStr; |
| | | } |
| | | return str.toLowerCase().contains(testStr.toLowerCase()); |
| | | } |
| | | |
| | | /** |
| | | * 生成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 处理后的字符串,不符合规范返回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 + capitalize(str); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 去掉指定前缀 |
| | | * |
| | | * @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; |
| | | } |
| | | |
| | | /** |
| | | * 获得字符串对应byte数组 |
| | | * |
| | | * @param str 字符串 |
| | | * @param charset 编码,如果为<code>null</code>使用系统默认编码 |
| | | * @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 (!str.startsWith(prefix)) { |
| | | str = prefix + str; |
| | | } |
| | | return str; |
| | | } |
| | | |
| | | /** |
| | | * 如果给定字符串不是以suffix结尾的,在尾部补充 suffix |
| | | * |
| | | * @param str 字符串 |
| | | * @param suffix 后缀 |
| | | * @return 补充后的字符串 |
| | | */ |
| | | public static String addSuffixIfNot(String str, String suffix) { |
| | | if (isEmpty(str) || isEmpty(suffix)) { |
| | | return str; |
| | | } |
| | | if (!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> |
| | | * 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}; |
| | | } |
| | | // del length |
| | | int dellen = delimiter.length(); |
| | | // one more for the last |
| | | int maxparts = (str.length() / dellen) + 2; |
| | | 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为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length<br> |
| | | * 如果经过修正的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 结束的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 (StringUtils.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 (StringUtils.isBlank(str)) { |
| | | // return false; |
| | | // } |
| | | // if (str.length() < 2) { |
| | | // return false; |
| | | // } |
| | | // |
| | | // return str.charAt(0) == prefix && str.charAt(str.length() - 1) == suffix; |
| | | // } |
| | | |
| | | /** |
| | | * 重复某个字符 |
| | | * |
| | | * @param c 被重复的字符 |
| | | * @param count 重复的数目 |
| | | * @return 重复字符字符串 |
| | | */ |
| | | 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); |
| | | } |
| | | |
| | | /** |
| | | * 重复某个字符串 |
| | | * |
| | | * @param str 被重复的字符 |
| | | * @param count 重复的数目 |
| | | * @return 重复字符字符串 |
| | | */ |
| | | 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; |
| | | // n <<= 1相当于n *2 |
| | | for (n = len; n < size - n; n <<= 1) { |
| | | System.arraycopy(array, 0, array, n, n); |
| | | } |
| | | System.arraycopy(array, 0, array, n, size - n); |
| | | return new String(array); |
| | | } |
| | | |
| | | /** |
| | | * 比较两个字符串(大小写敏感)。 |
| | | * <p> |
| | | * <pre> |
| | | * equals(null, null) = true |
| | | * equals(null, "abc") = false |
| | | * equals("abc", null) = false |
| | | * equals("abc", "abc") = true |
| | | * equals("abc", "ABC") = 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); |
| | | } |
| | | |
| | | /** |
| | | * 比较两个字符串(大小写不敏感)。 |
| | | * <p> |
| | | * <pre> |
| | | * equalsIgnoreCase(null, null) = true |
| | | * equalsIgnoreCase(null, "abc") = false |
| | | * equalsIgnoreCase("abc", null) = false |
| | | * equalsIgnoreCase("abc", "abc") = true |
| | | * equalsIgnoreCase("abc", "ABC") = 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 参数值 |
| | | * @return 格式化后的文本 |
| | | */ |
| | | public static String format(String template, Object... values) { |
| | | if (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 {b}", map) ----> aValue and bValue |
| | | * |
| | | * @param template 文本模板,被替换的部分用 {key} 表示 |
| | | * @param map 参数值对 |
| | | * @return 格式化后的文本 |
| | | */ |
| | | public static String format(String template, Map<?, ?> map) { |
| | | if (null == map || map.isEmpty()) { |
| | | return template; |
| | | } |
| | | |
| | | for (Map.Entry<?, ?> entry : map.entrySet()) { |
| | | template = template.replace("{" + entry.getKey() + "}", entry.getValue().toString()); |
| | | } |
| | | return template; |
| | | } |
| | | |
| | | /** |
| | | * 编码字符串 |
| | | * |
| | | * @param str 字符串 |
| | | * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 |
| | | * @return 编码后的字节码 |
| | | */ |
| | | public static byte[] bytes(String str, String charset) { |
| | | return bytes(str, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset)); |
| | | } |
| | | |
| | | /** |
| | | * 编码字符串 |
| | | * |
| | | * @param str 字符串 |
| | | * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 |
| | | * @return 编码后的字节码 |
| | | */ |
| | | public static byte[] bytes(String str, Charset charset) { |
| | | if (str == null) { |
| | | return null; |
| | | } |
| | | |
| | | if (null == charset) { |
| | | return str.getBytes(); |
| | | } |
| | | return str.getBytes(charset); |
| | | } |
| | | |
| | | /** |
| | | * 将byte数组转为字符串 |
| | | * |
| | | * @param bytes byte数组 |
| | | * @param charset 字符集 |
| | | * @return 字符串 |
| | | */ |
| | | public static String str(byte[] bytes, String charset) { |
| | | return str(bytes, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset)); |
| | | } |
| | | |
| | | /** |
| | | * 解码字节码 |
| | | * |
| | | * @param data 字符串 |
| | | * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 |
| | | * @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数据转换为字符串 |
| | | * |
| | | * @param data 数据 |
| | | * @param charset 字符集,如果为空使用当前系统字符集 |
| | | * @return 字符串 |
| | | */ |
| | | public static String str(ByteBuffer data, String charset) { |
| | | if (data == null) { |
| | | return null; |
| | | } |
| | | |
| | | return str(data, Charset.forName(charset)); |
| | | } |
| | | |
| | | /** |
| | | * 将编码的byteBuffer数据转换为字符串 |
| | | * |
| | | * @param data 数据 |
| | | * @param charset 字符集,如果为空使用当前系统字符集 |
| | | * @return 字符串 |
| | | */ |
| | | public static String str(ByteBuffer data, Charset charset) { |
| | | if (null == charset) { |
| | | charset = Charset.defaultCharset(); |
| | | } |
| | | return charset.decode(data).toString(); |
| | | } |
| | | |
| | | /** |
| | | * 字符串转换为byteBuffer |
| | | * |
| | | * @param str 字符串 |
| | | * @param charset 编码 |
| | | * @return byteBuffer |
| | | */ |
| | | public static ByteBuffer byteBuffer(String str, String charset) { |
| | | return ByteBuffer.wrap(StringUtils.bytes(str, charset)); |
| | | } |
| | | |
| | | /** |
| | | * 以 conjunction 为分隔符将多个对象转换为字符串 |
| | | * |
| | | * @param conjunction 分隔符 |
| | | * @param objs 数组 |
| | | * @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(); |
| | | } |
| | | |
| | | /** |
| | | * 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br> |
| | | * 例如:HelloWorld->hello_world |
| | | * |
| | | * @param camelCaseStr 转换前的驼峰式命名的字符串 |
| | | * @return 转换后下划线大写方式命名的字符串 |
| | | */ |
| | | public static String camelCaseToPath(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("/"); |
| | | } |
| | | } |
| | | isPreUpperCase = true; |
| | | } else { |
| | | isPreUpperCase = false; |
| | | } |
| | | sb.append(Character.toLowerCase(c)); |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br> |
| | | * 例如:HelloWorld->hello_world |
| | | * |
| | | * @param camelCaseStr 转换前的驼峰式命名的字符串 |
| | | * @return 转换后下划线大写方式命名的字符串 |
| | | */ |
| | | public static String camelCaseToUnderline(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(); |
| | | } |
| | | |
| | | /** |
| | | * 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> |
| | | * 例如:hello_world->HelloWorld |
| | | * |
| | | * @param name 转换前的下划线大写方式命名的字符串 |
| | | * @return 转换后的驼峰式命名的字符串 |
| | | */ |
| | | public static String underlineToCamelCase(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; |
| | | } |
| | | |
| | | /** |
| | | * 创建StringBuilder对象 |
| | | * |
| | | * @return StringBuilder对象 |
| | | */ |
| | | public static StringBuilder builder() { |
| | | return new StringBuilder(); |
| | | } |
| | | |
| | | /** |
| | | * 创建StringBuilder对象 |
| | | * |
| | | * @return StringBuilder对象 |
| | | */ |
| | | public static StringBuilder builder(int capacity) { |
| | | return new StringBuilder(capacity); |
| | | } |
| | | |
| | | /** |
| | | * 创建StringBuilder对象 |
| | | * |
| | | * @return StringBuilder对象 |
| | | */ |
| | | public static StringBuilder builder(String... strs) { |
| | | final StringBuilder sb = new StringBuilder(); |
| | | for (String str : strs) { |
| | | sb.append(str); |
| | | } |
| | | return sb; |
| | | } |
| | | |
| | | |
| | | public static String concatLikeStart(String value) { |
| | | return concatLike(value, 1); |
| | | } |
| | | |
| | | public static String concatLikeEnd(String value) { |
| | | return concatLike(value, 2); |
| | | } |
| | | |
| | | public static String concatLikeAll(String value) { |
| | | return concatLike(value, -1); |
| | | } |
| | | |
| | | /** |
| | | * @param value |
| | | * @param type |
| | | * @return |
| | | */ |
| | | public static String concatLike(String value, Integer type) { |
| | | if (isEmpty(value)) { |
| | | return null; |
| | | } |
| | | StringBuilder builder = new StringBuilder(value.length() + 3); |
| | | switch (type) { |
| | | case 1: |
| | | builder.append("%").append(value); |
| | | break; |
| | | case 2: |
| | | builder.append(value).append("%"); |
| | | break; |
| | | case 3: |
| | | builder.append(value); |
| | | break; |
| | | default: |
| | | builder.append("%").append(value).append("%"); |
| | | } |
| | | return builder.toString(); |
| | | } |
| | | |
| | | /** |
| | | * 获得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 字符集,如果此字段为空,则解码的结果取决于平台 |
| | | * @return 编码后的字节码 |
| | | */ |
| | | 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)); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 解码字节码 |
| | | * |
| | | * @param data 字符串 |
| | | * @param charset 字符集,如果此字段为空,则解码的结果取决于平台 |
| | | * @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)); |
| | | } |
| | | } |
| | | |
| | | // /** |
| | | // * 首字母变大写 |
| | | // */ |
| | | // 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; |
| | | // } |
| | | |
| | | |
| | | /** |
| | | * Description:把数字转化为指定长度的字符串编号,不足位数字前补0,超过或与指定长度相等返回原数值 |
| | | * 例如:23转化为4位字符编号 => "0023" |
| | | * |
| | | * @param val 原数值 |
| | | * @param num 字符串长度 |
| | | * @return java.lang.String |
| | | * @author fanhq |
| | | * @date 2020/4/17 9:44 |
| | | */ |
| | | public static String intToStringCode(Integer val, Integer num) { |
| | | int i = num - val.toString().length(); |
| | | StringBuffer sbf = new StringBuffer(); |
| | | for (int k = 0; k < i; k++) { |
| | | sbf.append("0"); |
| | | } |
| | | return sbf.append(val.toString()).toString(); |
| | | } |
| | | |
| | | public static String match(String message, String regex) { |
| | | Pattern p = Pattern.compile(regex); |
| | | Matcher m = p.matcher(message); |
| | | while (m.find()) { |
| | | return m.group(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | public static String lpad(Integer length, String data, char text) { |
| | | if (data.length() >= length) { |
| | | return data; |
| | | } |
| | | StringBuffer stringBuffer = new StringBuffer(); |
| | | for (int i = data.length(); i < length; i++) { |
| | | stringBuffer.append(text); |
| | | } |
| | | return stringBuffer.append(data).toString(); |
| | | } |
| | | } |