com.base4j.util.StrUtil Maven / Gradle / Ivy
The newest version!
package com.base4j.util;
import java.io.StringReader;
import java.io.StringWriter;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* 字符串工具类
*
* @author xxx
*/
public class StrUtil {
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 = "&";
public static final String HTML_QUOTE = """;
public static final String HTML_LT = "<";
public static final String HTML_GT = ">";
public static final String EMPTY_JSON = "{}";
// ------------------------------------------------------------------------ Blank
/**
* 字符串是否为空白 空白的定义如下:
* 1、为null
* 2、为不可见字符(如空格)
* 3、""
*
* @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;
}
/**
* 字符串是否为非空白 空白的定义如下:
* 1、不为null
* 2、不为不可见字符(如空格)
* 3、不为""
*
* @param str 被检测的字符串
* @return 是否为非空
*/
public static boolean isNotBlank(String str) {
return false == isBlank(str);
}
/**
* 是否包含空字符串
*
* @param strs 字符串列表
* @return 是否包含空字符串
*/
public static boolean hasBlank(String... strs) {
if (CollectionUtil.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 (CollectionUtil.isEmpty(strs)) {
return true;
}
for (String str : strs) {
if (isNotBlank(str)) {
return false;
}
}
return true;
}
// ------------------------------------------------------------------------ Empty
/**
* 字符串是否为空,空的定义如下 1、为null
* 2、为""
*
* @param str 被检测的字符串
* @return 是否为空
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* 字符串是否为非空白 空白的定义如下:
* 1、不为null
* 2、不为""
*
* @param str 被检测的字符串
* @return 是否为非空
*/
public static boolean isNotEmpty(String str) {
return false == isEmpty(str);
}
/**
* 当给定字符串为null时,转换为Empty
*
* @param str 被转换的字符串
* @return 转换后的字符串
*/
public static String nullToEmpty(String str) {
return nullToDefault(str, EMPTY);
}
/**
* 如果字符串是null
,则返回指定默认字符串,否则返回字符串本身。
*
*
* nullToDefault(null, "default") = "default"
* nullToDefault("", "default") = ""
* nullToDefault(" ", "default") = " "
* nullToDefault("bat", "default") = "bat"
*
*
* @param str 要转换的字符串
* @param defaultStr 默认字符串
* @return 字符串本身或指定的默认字符串
*/
public static String nullToDefault(String str, String defaultStr) {
return (str == null) ? defaultStr : str;
}
/**
* 当给定字符串为空字符串时,转换为null
*
* @param str 被转换的字符串
* @return 转换后的字符串
*/
public static String emptyToNull(String str) {
return isEmpty(str) ? null : str;
}
/**
* 是否包含空字符串
*
* @param strs 字符串列表
* @return 是否包含空字符串
*/
public static boolean hasEmpty(String... strs) {
if (CollectionUtil.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 (CollectionUtil.isEmpty(strs)) {
return true;
}
for (String str : strs) {
if (isNotEmpty(str)) {
return false;
}
}
return true;
}
// ------------------------------------------------------------------------ Trim
/**
* 除去字符串头尾部的空白,如果字符串是null
,依然返回null
。
*
*
* 注意,和String.trim
不同,此方法使用Character.isWhitespace
来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
*
* trim(null) = null
* trim("") = ""
* trim(" ") = ""
* trim("abc") = "abc"
* trim(" abc ") = "abc"
*
*
*
*
* @param str 要处理的字符串
* @return 除去空白的字符串,如果原字串为null
,则返回null
*/
public static String trim(String str) {
return (null == str) ? null : trim(str, 0);
}
/**
* 给定字符串数组全部做去首尾空格
*
* @param strs 字符串数组
*/
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();
}
}
}
/**
* 除去字符串头部的空白,如果字符串是 null
,则返回null
。
*
*
* 注意,和String.trim
不同,此方法使用Character.isWhitespace
来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
*
* trimStart(null) = null
* trimStart("") = ""
* trimStart("abc") = "abc"
* trimStart(" abc") = "abc"
* trimStart("abc ") = "abc "
* trimStart(" abc ") = "abc "
*
*
*
*
* @param str 要处理的字符串
* @return 除去空白的字符串,如果原字串为null
或结果字符串为""
,则返回 null
*/
public static String trimStart(String str) {
return trim(str, -1);
}
/**
* 除去字符串尾部的空白,如果字符串是null
,则返回null
。
*
*
* 注意,和String.trim
不同,此方法使用Character.isWhitespace
来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
*
*
* trimEnd(null) = null
* trimEnd("") = ""
* trimEnd("abc") = "abc"
* trimEnd(" abc") = " abc"
* trimEnd("abc ") = "abc"
* trimEnd(" abc ") = " abc"
*
*
*
*
* @param str 要处理的字符串
* @return 除去空白的字符串,如果原字串为null
或结果字符串为""
,则返回 null
*/
public static String trimEnd(String str) {
return trim(str, 1);
}
/**
* 除去字符串头尾部的空白符,如果字符串是null
,依然返回null
。
*
* @param str 要处理的字符串
* @param mode -1
表示trimStart,0
表示trim全部, 1
表示trimEnd
* @return 除去指定字符后的的字符串,如果原字串为null
,则返回null
*/
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 被监测字符串
* @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);
}
}
/**
* 是否包含特定字符,忽略大小写,如果给定两个参数都为null
,返回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或get方法对应的标准属性名
* 例如: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方法名
* 例如: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");
}
/**
* 去掉首部指定长度的字符串并将剩余字符串首字母小写
* 例如: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 + upperFirst(str);
}
/**
* 大写首字母
* 例如:str = name, return Name
*
* @param str 字符串
* @return 字符串
*/
public static String upperFirst(String str) {
return Character.toUpperCase(str.charAt(0)) + str.substring(1);
}
/**
* 小写首字母
* 例如: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;
}
/**
* 忽略大小写去掉指定后缀
*
* @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;
}
/**
* 清理空白字符
*
* @param str 被清理的字符串
* @return 清理后的字符串
*/
public static String cleanBlank(String str) {
if (str == null) {
return null;
}
return str.replaceAll("\\s*", EMPTY);
}
/**
* 切分字符串
* a#b#c -> [a,b,c]
* a##b#c -> [a,"",b,c]
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @return 切分后的集合
*/
public static List split(String str, char separator) {
return split(str, separator, 0);
}
/**
* 切分字符串
*
* @param str 被切分的字符串
* @param separator 分隔符字符
* @param limit 限制分片数
* @return 切分后的集合
*/
public static List split(String str, char separator, int limit) {
if (str == null) {
return null;
}
List list = new ArrayList(limit == 0 ? 16 : limit);
if (limit == 1) {
list.add(str);
return list;
}
boolean isNotEnd = true; // 未结束切分的标志
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());
// 当达到切分上限-1的量时,将所剩字符全部作为最后一个串
if (limit != 0 && list.size() == limit - 1) {
isNotEnd = false;
}
} else {
sb.append(c);
}
}
list.add(sb.toString());// 加入尾串
return list;
}
/**
* 切分字符串
* 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
* index从0开始计算,最后一个字符为-1
* 如果from和to位置一样,返回 "" example: abcdefgh 2 3 -> c abcdefgh 2 -3 -> cde
*
* @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 (toIndex == 0) {
toIndex = len;
}
}
if (toIndex < 0) {
toIndex = len + toIndex;
}
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 (StrUtil.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 (StrUtil.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;
for (n = len; n < size - n; n <<= 1) {// n <<= 1相当于n *2
System.arraycopy(array, 0, array, n, n);
}
System.arraycopy(array, 0, array, n, size - n);
return new String(array);
}
/**
* 比较两个字符串(大小写敏感)。
*
*
* equals(null, null) = true
* equals(null, "abc") = false
* equals("abc", null) = false
* equals("abc", "abc") = true
* equals("abc", "ABC") = false
*
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
* @return 如果两个字符串相同,或者都是null
,则返回true
*/
public static boolean equals(String str1, String str2) {
if (str1 == null) {
return str2 == null;
}
return str1.equals(str2);
}
/**
* 比较两个字符串(大小写不敏感)。
*
*
* equalsIgnoreCase(null, null) = true
* equalsIgnoreCase(null, "abc") = false
* equalsIgnoreCase("abc", null) = false
* equalsIgnoreCase("abc", "abc") = true
* equalsIgnoreCase("abc", "ABC") = true
*
*
* @param str1 要比较的字符串1
* @param str2 要比较的字符串2
* @return 如果两个字符串相同,或者都是null
,则返回true
*/
public static boolean equalsIgnoreCase(String str1, String str2) {
if (str1 == null) {
return str2 == null;
}
return str1.equalsIgnoreCase(str2);
}
/**
* 格式化文本, {} 表示占位符
* 例如:date2str("aaa {} ccc", "bbb") ----> aaa bbb ccc
*
* @param template 文本模板,被替换的部分用 {} 表示
* @param values 参数值
* @return 格式化后的文本
*/
public static String format(String template, Object... values) {
if (CollectionUtil.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} 占位
* map = {a: "aValue", b: "bValue"}
* date2str("{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 (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);
}
/**
* 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
* 2、对象数组会调用Arrays.toString方法
*
* @param obj 对象
* @return 字符串
*/
public static String utf8Str(Object obj) {
return str(obj, CharsetUtil.CHARSET_UTF_8);
}
/**
* 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
* 2、对象数组会调用Arrays.toString方法
*
* @param obj 对象
* @param charsetName 字符集
* @return 字符串
*/
public static String str(Object obj, String charsetName) {
return str(obj, Charset.forName(charsetName));
}
/**
* 将对象转为字符串
* 1、Byte数组和ByteBuffer会被转换为对应字符串的数组
* 2、对象数组会调用Arrays.toString方法
*
* @param obj 对象
* @param charset 字符集
* @return 字符串
*/
public static String str(Object obj, Charset charset) {
if (null == obj) {
return null;
}
if (obj instanceof byte[] || obj instanceof Byte[]) {
return str((Byte[]) obj, charset);
}
if (obj instanceof ByteBuffer) {
return str((ByteBuffer) obj, charset);
}
if (ObjectUtil.isArray(obj)) {
return Arrays.toString((Object[]) obj);
}
return obj.toString();
}
/**
* 将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(StrUtil.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();
}
/**
* 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。
* 例如:HelloWorld->hello_world
*
* @param camelCaseStr 转换前的驼峰式命名的字符串
* @return 转换后下划线大写方式命名的字符串
*/
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();
}
/**
* 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
* 例如:hello_world->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
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();
}
/**
* 创建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;
}
/**
* 获得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();
}
}