概述
字符串操作是Java编程中最基础也最常用的功能之一。本文将介绍一个全面的字符串操作工具类StringUtils,它集成了各种常见的字符串处理方法,可以帮助开发者更高效地处理字符串相关任务。
工具类
StringUtils工具类提供了超过100个静态方法,涵盖了字符串处理的各个方面,包括:
-
空值/空白检查
-
截取与分割
-
连接与拼接
-
转换与格式化
-
搜索与比较
-
编码与加密
-
校验与验证
-
统计与分析
核心功能详解
1. 空值与空白检查
-
isEmpty()/isNotEmpty():检查字符串是否为null或空字符串 -
isBlank()/isNotBlank():检查字符串是否为null或只包含空白字符 -
trim()/trimAll()/trimToSingle():去除字符串空白的不同方式
2. 截取与分割
-
substring()系列方法:提供多种截取方式,支持负数索引 -
split()/splitAndTrim():字符串分割,可自动去除分割后元素的空白 -
splitByLength():按固定长度分割字符串 -
substringBetween():截取两个字符串之间的内容
3. 连接与拼接
-
join():支持数组和集合的字符串连接 -
多种填充方法:
leftPad()、rightPad()、center() -
重复方法:
repeat()可重复字符或字符串
4. 转换与格式化
-
大小写转换:
capitalize()、uncapitalize() -
命名风格转换:
toCamelCase()、fromCamelCase() -
特殊格式转换:
toTitleCase()、toSafeFileName() -
编码转换:
toUnicode()、fromUnicode() -
转义处理:
escapeHtml()、toSafeJsonString()
5. 搜索与比较
-
包含检查:
containsIgnoreCase() -
开头/结尾检查:
startsWithIgnoreCase()、endsWithIgnoreCase() -
相似度计算:
similarity()基于Levenshtein距离 -
比较方法:
compare()、compareIgnoreCase()提供null安全比较
6. 编码与加密
-
Base64编码:
toBase64()、fromBase64() -
哈希计算:
md5()、sha1()、sha256()、sha512() -
校验值计算:
crc32()
7. 校验与验证
-
类型检查:
isAlpha()、isNumeric()、isAlphanumeric() -
格式验证:
isEmail()、isPhoneNumber()、isIdCardNumber()
8. 统计与分析
-
频率统计:
charFrequency()、substringFrequency() -
最值查找:
longestWord()、shortestWord() -
字符分析:
mostCommonChar()、leastCommonChar() -
字符提取:
uniqueChars()、digitChars()等
工具类模版
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 字符串操作工具类
*/
public class StringUtils {
private static final String EMPTY = "";
private static final int INDEX_NOT_FOUND = -1;
/**
* 判断字符串是否为空
* @param str 字符串
* @return 如果字符串为null或空字符串,返回true
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* 判断字符串是否不为空
* @param str 字符串
* @return 如果字符串不为null且长度大于0,返回true
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
* 判断字符串是否为空白(包括空格、制表符等)
* @param str 字符串
* @return 如果字符串为null或只包含空白字符,返回true
*/
public static boolean isBlank(String str) {
if (isEmpty(str)) {
return true;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isWhitespace(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 判断字符串是否不为空白
* @param str 字符串
* @return 如果字符串不为null且包含非空白字符,返回true
*/
public static boolean isNotBlank(String str) {
return !isBlank(str);
}
/**
* 去除字符串两端的空白字符
* @param str 字符串
* @return 去除两端空白后的字符串,如果输入为null则返回null
*/
public static String trim(String str) {
return str == null ? null : str.trim();
}
/**
* 去除字符串中的所有空白字符
* @param str 字符串
* @return 去除所有空白后的字符串
*/
public static String trimAll(String str) {
if (isEmpty(str)) {
return str;
}
return str.replaceAll("\\s+", "");
}
/**
* 去除字符串中的空白字符(保留一个空格)
* @param str 字符串
* @return 处理后的字符串
*/
public static String trimToSingle(String str) {
if (isEmpty(str)) {
return str;
}
return str.replaceAll("\\s+", " ").trim();
}
/**
* 截取字符串
* @param str 字符串
* @param start 开始位置
* @return 截取后的字符串
*/
public static String substring(String str, int start) {
if (str == null) {
return null;
}
if (start < 0) {
start = str.length() + start;
}
if (start < 0) {
start = 0;
}
if (start > str.length()) {
return EMPTY;
}
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;
}
if (end < 0) {
end = str.length() + end;
}
if (start < 0) {
start = str.length() + start;
}
if (end > str.length()) {
end = str.length();
}
if (start > end) {
return EMPTY;
}
if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}
return str.substring(start, end);
}
/**
* 截取两个字符串之间的内容
* @param str 字符串
* @param open 开始字符串
* @param close 结束字符串
* @return 截取到的字符串
*/
public static String substringBetween(String str, String open, String close) {
if (str == null || open == null || close == null) {
return null;
}
int start = str.indexOf(open);
if (start != INDEX_NOT_FOUND) {
int end = str.indexOf(close, start + open.length());
if (end != INDEX_NOT_FOUND) {
return str.substring(start + open.length(), end);
}
}
return null;
}
/**
* 截取字符串左边指定长度的字符
* @param str 字符串
* @param len 长度
* @return 截取后的字符串
*/
public static String left(String str, int len) {
if (str == null) {
return null;
}
if (len < 0) {
return EMPTY;
}
if (str.length() <= len) {
return str;
}
return str.substring(0, len);
}
/**
* 截取字符串右边指定长度的字符
* @param str 字符串
* @param len 长度
* @return 截取后的字符串
*/
public static String right(String str, int len) {
if (str == null) {
return null;
}
if (len < 0) {
return EMPTY;
}
if (str.length() <= len) {
return str;
}
return 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;
}
if (len < 0 || pos > str.length()) {
return EMPTY;
}
if (pos < 0) {
pos = 0;
}
if (str.length() <= pos + len) {
return str.substring(pos);
}
return str.substring(pos, pos + len);
}
/**
* 字符串分割
* @param str 字符串
* @param separator 分隔符
* @return 分割后的字符串数组
*/
public static String[] split(String str, String separator) {
if (isEmpty(str)) {
return new String[0];
}
if (separator == null) {
return new String[]{str};
}
return str.split(separator);
}
/**
* 字符串分割,并去除每个元素两端的空白
* @param str 字符串
* @param separator 分隔符
* @return 分割并去除空白后的字符串数组
*/
public static String[] splitAndTrim(String str, String separator) {
if (isEmpty(str)) {
return new String[0];
}
String[] array = str.split(separator);
for (int i = 0; i < array.length; i++) {
array[i] = array[i].trim();
}
return array;
}
/**
* 将字符串按固定长度分割
* @param str 字符串
* @param size 每段长度
* @return 分割后的字符串数组
*/
public static String[] splitByLength(String str, int size) {
if (isEmpty(str) || size <= 0) {
return new String[0];
}
int len = str.length();
int count = (len + size - 1) / size;
String[] result = new String[count];
for (int i = 0; i < count; i++) {
int start = i * size;
int end = Math.min(start + size, len);
result[i] = str.substring(start, end);
}
return result;
}
/**
* 将字符串数组连接成一个字符串
* @param array 字符串数组
* @param separator 分隔符
* @return 连接后的字符串
*/
public static String join(String[] array, String separator) {
if (array == null) {
return null;
}
if (separator == null) {
separator = EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
if (i > 0) {
sb.append(separator);
}
if (array[i] != null) {
sb.append(array[i]);
}
}
return sb.toString();
}
/**
* 将集合连接成一个字符串
* @param collection 集合
* @param separator 分隔符
* @return 连接后的字符串
*/
public static String join(Iterable<?> collection, String separator) {
if (collection == null) {
return null;
}
if (separator == null) {
separator = EMPTY;
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Object item : collection) {
if (first) {
first = false;
} else {
sb.append(separator);
}
sb.append(item);
}
return sb.toString();
}
/**
* 字符串反转
* @param str 字符串
* @return 反转后的字符串
*/
public static String reverse(String str) {
if (str == null) {
return null;
}
return new StringBuilder(str).reverse().toString();
}
/**
* 删除字符串中的指定字符
* @param str 字符串
* @param remove 要删除的字符
* @return 处理后的字符串
*/
public static String remove(String str, char remove) {
if (isEmpty(str)) {
return str;
}
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);
}
/**
* 删除字符串中的指定字符串
* @param str 字符串
* @param remove 要删除的字符串
* @return 处理后的字符串
*/
public static String remove(String str, String remove) {
if (isEmpty(str) || isEmpty(remove)) {
return str;
}
return str.replace(remove, EMPTY);
}
/**
* 删除字符串中的所有空白字符
* @param str 字符串
* @return 处理后的字符串
*/
public static String removeWhitespace(String str) {
if (isEmpty(str)) {
return str;
}
return str.replaceAll("\\s+", EMPTY);
}
/**
* 替换字符串中的指定字符
* @param str 字符串
* @param searchChar 要替换的字符
* @param replaceChar 替换为的字符
* @return 替换后的字符串
*/
public static String replace(String str, char searchChar, char replaceChar) {
if (str == null) {
return null;
}
return str.replace(searchChar, replaceChar);
}
/**
* 替换字符串中的指定字符串
* @param str 字符串
* @param searchStr 要替换的字符串
* @param replaceStr 替换为的字符串
* @return 替换后的字符串
*/
public static String replace(String str, String searchStr, String replaceStr) {
if (isEmpty(str) || isEmpty(searchStr) || replaceStr == null) {
return str;
}
return str.replace(searchStr, replaceStr);
}
/**
* 替换字符串中的指定字符串(只替换第一个匹配项)
* @param str 字符串
* @param searchStr 要替换的字符串
* @param replaceStr 替换为的字符串
* @return 替换后的字符串
*/
public static String replaceFirst(String str, String searchStr, String replaceStr) {
if (isEmpty(str) || isEmpty(searchStr) || replaceStr == null) {
return str;
}
return str.replaceFirst(Pattern.quote(searchStr), replaceStr);
}
/**
* 替换字符串中的指定字符串(忽略大小写)
* @param str 字符串
* @param searchStr 要替换的字符串
* @param replaceStr 替换为的字符串
* @return 替换后的字符串
*/
public static String replaceIgnoreCase(String str, String searchStr, String replaceStr) {
if (isEmpty(str) || isEmpty(searchStr) || replaceStr == null) {
return str;
}
return Pattern.compile(searchStr, Pattern.CASE_INSENSITIVE)
.matcher(str)
.replaceAll(Matcher.quoteReplacement(replaceStr));
}
/**
* 将字符串首字母大写
* @param str 字符串
* @return 首字母大写的字符串
*/
public static String capitalize(String str) {
if (isEmpty(str)) {
return str;
}
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
/**
* 将字符串首字母小写
* @param str 字符串
* @return 首字母小写的字符串
*/
public static String uncapitalize(String str) {
if (isEmpty(str)) {
return str;
}
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
/**
* 将字符串转换为驼峰命名法
* @param str 字符串
* @param separator 分隔符
* @return 驼峰命名法的字符串
*/
public static String toCamelCase(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = "_";
}
String[] parts = str.split(separator);
StringBuilder sb = new StringBuilder(parts[0].toLowerCase());
for (int i = 1; i < parts.length; i++) {
sb.append(capitalize(parts[i].toLowerCase()));
}
return sb.toString();
}
/**
* 将驼峰命名法的字符串转换为指定分隔符的字符串
* @param str 字符串
* @param separator 分隔符
* @return 转换后的字符串
*/
public static String fromCamelCase(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = "_";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isUpperCase(c) && i > 0) {
sb.append(separator);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 统计子字符串在字符串中出现的次数
* @param str 字符串
* @param sub 子字符串
* @return 出现次数
*/
public static int countMatches(String str, String sub) {
if (isEmpty(str) || isEmpty(sub)) {
return 0;
}
int count = 0;
int idx = 0;
while ((idx = str.indexOf(sub, idx)) != INDEX_NOT_FOUND) {
count++;
idx += sub.length();
}
return count;
}
/**
* 检查字符串是否以指定字符串开头(忽略大小写)
* @param str 字符串
* @param prefix 前缀
* @return 是否以指定字符串开头
*/
public static boolean startsWithIgnoreCase(String str, String prefix) {
if (str == null || prefix == null) {
return str == null && prefix == null;
}
if (prefix.length() > str.length()) {
return false;
}
return str.regionMatches(true, 0, prefix, 0, prefix.length());
}
/**
* 检查字符串是否以指定字符串结尾(忽略大小写)
* @param str 字符串
* @param suffix 后缀
* @return 是否以指定字符串结尾
*/
public static boolean endsWithIgnoreCase(String str, String suffix) {
if (str == null || suffix == null) {
return str == null && suffix == null;
}
if (suffix.length() > str.length()) {
return false;
}
return str.regionMatches(true, str.length() - suffix.length(), suffix, 0, suffix.length());
}
/**
* 检查字符串是否包含指定字符(忽略大小写)
* @param str 字符串
* @param searchStr 要查找的字符串
* @return 是否包含
*/
public static boolean containsIgnoreCase(String str, String searchStr) {
if (str == null || searchStr == null) {
return false;
}
return str.toLowerCase().contains(searchStr.toLowerCase());
}
/**
* 检查字符串是否只包含字母
* @param str 字符串
* @return 是否只包含字母
*/
public static boolean isAlpha(String str) {
if (isEmpty(str)) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isLetter(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 检查字符串是否只包含数字
* @param str 字符串
* @return 是否只包含数字
*/
public static boolean isNumeric(String str) {
if (isEmpty(str)) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 检查字符串是否只包含字母或数字
* @param str 字符串
* @return 是否只包含字母或数字
*/
public static boolean isAlphanumeric(String str) {
if (isEmpty(str)) {
return false;
}
for (int i = 0; i < str.length(); i++) {
if (!Character.isLetterOrDigit(str.charAt(i))) {
return false;
}
}
return true;
}
/**
* 检查字符串是否是有效的邮箱地址
* @param str 字符串
* @return 是否是有效的邮箱地址
*/
public static boolean isEmail(String str) {
if (isEmpty(str)) {
return false;
}
String regex = "^[\\w-]+(\\.[\\w-]+)*@[\\w-]+(\\.[\\w-]+)+$";
return Pattern.matches(regex, str);
}
/**
* 检查字符串是否是有效的手机号码
* @param str 字符串
* @return 是否是有效的手机号码
*/
public static boolean isPhoneNumber(String str) {
if (isEmpty(str)) {
return false;
}
String regex = "^1[3-9]\\d{9}$";
return Pattern.matches(regex, str);
}
/**
* 检查字符串是否是有效的身份证号码
* @param str 字符串
* @return 是否是有效的身份证号码
*/
public static boolean isIdCardNumber(String str) {
if (isEmpty(str)) {
return false;
}
String regex = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$";
return Pattern.matches(regex, str);
}
/**
* 生成指定长度的随机字符串
* @param length 长度
* @return 随机字符串
*/
public static String random(int length) {
return random(length, false);
}
/**
* 生成指定长度的随机字符串
* @param length 长度
* @param lettersOnly 是否只包含字母
* @return 随机字符串
*/
public static String random(int length, boolean lettersOnly) {
if (length <= 0) {
return EMPTY;
}
String chars = lettersOnly ? "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
: "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(chars.charAt(random.nextInt(chars.length())));
}
return sb.toString();
}
/**
* 生成指定长度的随机数字字符串
* @param length 长度
* @return 随机数字字符串
*/
public static String randomNumeric(int length) {
if (length <= 0) {
return EMPTY;
}
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(random.nextInt(10));
}
return sb.toString();
}
/**
* 字符串填充(左填充)
* @param str 字符串
* @param size 总长度
* @param padChar 填充字符
* @return 填充后的字符串
*/
public static String leftPad(String str, int size, char padChar) {
if (str == null) {
return null;
}
int pads = size - str.length();
if (pads <= 0) {
return str;
}
return repeat(padChar, pads) + str;
}
/**
* 字符串填充(右填充)
* @param str 字符串
* @param size 总长度
* @param padChar 填充字符
* @return 填充后的字符串
*/
public static String rightPad(String str, int size, char padChar) {
if (str == null) {
return null;
}
int pads = size - str.length();
if (pads <= 0) {
return str;
}
return str + repeat(padChar, pads);
}
/**
* 重复字符
* @param ch 字符
* @param repeat 重复次数
* @return 重复后的字符串
*/
public static String repeat(char ch, int repeat) {
if (repeat <= 0) {
return EMPTY;
}
char[] buf = new char[repeat];
Arrays.fill(buf, ch);
return new String(buf);
}
/**
* 重复字符串
* @param str 字符串
* @param repeat 重复次数
* @return 重复后的字符串
*/
public static String repeat(String str, int repeat) {
if (str == null || repeat <= 0) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < repeat; i++) {
sb.append(str);
}
return sb.toString();
}
/**
* 字符串居中
* @param str 字符串
* @param size 总长度
* @param padChar 填充字符
* @return 居中后的字符串
*/
public static String center(String str, int size, char padChar) {
if (str == null || size <= 0) {
return str;
}
int strLen = str.length();
int pads = size - strLen;
if (pads <= 0) {
return str;
}
str = leftPad(str, strLen + pads / 2, padChar);
str = rightPad(str, size, padChar);
return str;
}
/**
* 转义HTML特殊字符
* @param str 字符串
* @return 转义后的字符串
*/
public static String escapeHtml(String str) {
if (isEmpty(str)) {
return str;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
switch (c) {
case '<':
sb.append("<");
break;
case '>':
sb.append(">");
break;
case '&':
sb.append("&");
break;
case '"':
sb.append(""");
break;
case '\'':
sb.append("'");
break;
default:
sb.append(c);
}
}
return sb.toString();
}
/**
* 反转义HTML特殊字符
* @param str 字符串
* @return 反转义后的字符串
*/
public static String unescapeHtml(String str) {
if (isEmpty(str)) {
return str;
}
return str.replace("<", "<")
.replace(">", ">")
.replace("&", "&")
.replace(""", "\"")
.replace("'", "'");
}
/**
* 将字符串转换为Unicode编码
* @param str 字符串
* @return Unicode编码字符串
*/
public static String toUnicode(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 (c > 127) {
sb.append("\\u").append(Integer.toHexString(c));
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 将Unicode编码字符串转换为普通字符串
* @param str Unicode编码字符串
* @return 普通字符串
*/
public static String fromUnicode(String str) {
if (isEmpty(str)) {
return str;
}
StringBuilder sb = new StringBuilder();
int i = 0;
while (i < str.length()) {
char c = str.charAt(i);
if (c == '\\' && i + 1 < str.length() && str.charAt(i + 1) == 'u') {
String hex = str.substring(i + 2, i + 6);
sb.append((char) Integer.parseInt(hex, 16));
i += 6;
} else {
sb.append(c);
i++;
}
}
return sb.toString();
}
/**
* 获取字符串的缩写形式
* @param str 字符串
* @param maxWidth 最大长度
* @return 缩写后的字符串
*/
public static String abbreviate(String str, int maxWidth) {
if (isEmpty(str)) {
return str;
}
if (maxWidth < 4) {
maxWidth = 4;
}
if (str.length() <= maxWidth) {
return str;
}
return str.substring(0, maxWidth - 3) + "...";
}
/**
* 获取字符串的缩写形式(中间省略)
* @param str 字符串
* @param maxWidth 最大长度
* @return 缩写后的字符串
*/
public static String abbreviateMiddle(String str, int maxWidth) {
if (isEmpty(str)) {
return str;
}
if (maxWidth < 4) {
maxWidth = 4;
}
if (str.length() <= maxWidth) {
return str;
}
int start = (maxWidth - 3) / 2;
int end = str.length() - (maxWidth - 3 - start);
return str.substring(0, start) + "..." + str.substring(end);
}
/**
* 计算两个字符串的相似度(基于Levenshtein距离)
* @param str1 字符串1
* @param str2 字符串2
* @return 相似度(0-1之间)
*/
public static double similarity(String str1, String str2) {
if (str1 == null || str2 == null) {
return 0.0;
}
if (str1.equals(str2)) {
return 1.0;
}
int distance = levenshteinDistance(str1, str2);
return 1.0 - (double) distance / Math.max(str1.length(), str2.length());
}
/**
* 计算两个字符串的Levenshtein距离
* @param str1 字符串1
* @param str2 字符串2
* @return Levenshtein距离
*/
public static int levenshteinDistance(String str1, String str2) {
if (str1 == null || str2 == null) {
throw new IllegalArgumentException("Strings must not be null");
}
int n = str1.length();
int m = str2.length();
if (n == 0) {
return m;
}
if (m == 0) {
return n;
}
int[][] d = new int[n + 1][m + 1];
for (int i = 0; i <= n; i++) {
d[i][0] = i;
}
for (int j = 0; j <= m; j++) {
d[0][j] = j;
}
for (int i = 1; i <= n; i++) {
char c1 = str1.charAt(i - 1);
for (int j = 1; j <= m; j++) {
char c2 = str2.charAt(j - 1);
int cost = (c1 == c2) ? 0 : 1;
d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + cost);
}
}
return d[n][m];
}
/**
* 提取字符串中的所有数字
* @param str 字符串
* @return 数字字符串
*/
public static String extractNumbers(String str) {
if (isEmpty(str)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isDigit(c)) {
sb.append(c);
}
}
return sb.toString();
}
/**
* 提取字符串中的所有字母
* @param str 字符串
* @return 字母字符串
*/
public static String extractLetters(String str) {
if (isEmpty(str)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isLetter(c)) {
sb.append(c);
}
}
return sb.toString();
}
/**
* 提取字符串中的所有字母和数字
* @param str 字符串
* @return 字母和数字字符串
*/
public static String extractAlphanumeric(String str) {
if (isEmpty(str)) {
return EMPTY;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isLetterOrDigit(c)) {
sb.append(c);
}
}
return sb.toString();
}
/**
* 将字符串转换为安全的文件名
* @param str 字符串
* @return 安全的文件名
*/
public static String toSafeFileName(String str) {
if (isEmpty(str)) {
return "file";
}
return str.replaceAll("[\\\\/:*?\"<>|]", "_");
}
/**
* 将字符串转换为安全的Java标识符
* @param str 字符串
* @return 安全的Java标识符
*/
public static String toSafeJavaIdentifier(String str) {
if (isEmpty(str)) {
return "var";
}
StringBuilder sb = new StringBuilder();
if (!Character.isJavaIdentifierStart(str.charAt(0))) {
sb.append("_");
}
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isJavaIdentifierPart(c)) {
sb.append(c);
} else {
sb.append("_");
}
}
return sb.toString();
}
/**
* 将字符串转换为安全的URL路径
* @param str 字符串
* @return 安全的URL路径
*/
public static String toSafeUrlPath(String str) {
if (isEmpty(str)) {
return "";
}
return str.replaceAll("[^a-zA-Z0-9-_.]", "_").replaceAll("_+", "_");
}
/**
* 将字符串转换为安全的XML内容
* @param str 字符串
* @return 安全的XML内容
*/
public static String toSafeXmlContent(String str) {
if (isEmpty(str)) {
return "";
}
return str.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("'", "'");
}
/**
* 将字符串转换为安全的JSON字符串内容
* @param str 字符串
* @return 安全的JSON字符串内容
*/
public static String toSafeJsonString(String str) {
if (isEmpty(str)) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
switch (c) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '/':
sb.append("\\/");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
if (c <= '\u001F') {
sb.append(String.format("\\u%04x", (int) c));
} else {
sb.append(c);
}
}
}
return sb.toString();
}
/**
* 将字符串转换为安全的SQL字符串内容
* @param str 字符串
* @return 安全的SQL字符串内容
*/
public static String toSafeSqlString(String str) {
if (isEmpty(str)) {
return "";
}
return str.replace("'", "''");
}
/**
* 将字符串转换为首字母大写的单词列表
* @param str 字符串
* @param separator 分隔符
* @return 首字母大写的单词列表
*/
public static String toTitleCase(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = " ";
}
String[] words = str.split(separator);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < words.length; i++) {
if (i > 0) {
sb.append(separator);
}
sb.append(capitalize(words[i]));
}
return sb.toString();
}
/**
* 将字符串转换为单词列表(驼峰命名法)
* @param str 字符串
* @return 单词列表
*/
public static List<String> toWordList(String str) {
List<String> words = new ArrayList<>();
if (isEmpty(str)) {
return words;
}
StringBuilder word = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isUpperCase(c) && word.length() > 0) {
words.add(word.toString());
word = new StringBuilder();
}
word.append(Character.toLowerCase(c));
}
if (word.length() > 0) {
words.add(word.toString());
}
return words;
}
/**
* 将字符串转换为字节数组(UTF-8编码)
* @param str 字符串
* @return 字节数组
*/
public static byte[] toBytes(String str) {
if (str == null) {
return null;
}
return str.getBytes(StandardCharsets.UTF_8);
}
/**
* 将字节数组转换为字符串(UTF-8编码)
* @param bytes 字节数组
* @return 字符串
*/
public static String fromBytes(byte[] bytes) {
if (bytes == null) {
return null;
}
return new String(bytes, StandardCharsets.UTF_8);
}
/**
* 将字符串转换为16进制表示
* @param str 字符串
* @return 16进制字符串
*/
public static String toHex(String str) {
if (isEmpty(str)) {
return str;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
sb.append(Integer.toHexString(str.charAt(i)));
}
return sb.toString();
}
/**
* 将16进制字符串转换为普通字符串
* @param hex 16进制字符串
* @return 普通字符串
*/
public static String fromHex(String hex) {
if (isEmpty(hex)) {
return hex;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hex.length(); i += 2) {
String str = hex.substring(i, i + 2);
sb.append((char) Integer.parseInt(str, 16));
}
return sb.toString();
}
/**
* 将字符串转换为Base64编码
* @param str 字符串
* @return Base64编码字符串
*/
public static String toBase64(String str) {
if (str == null) {
return null;
}
return Base64.getEncoder().encodeToString(str.getBytes(StandardCharsets.UTF_8));
}
/**
* 将Base64编码字符串转换为普通字符串
* @param base64 Base64编码字符串
* @return 普通字符串
*/
public static String fromBase64(String base64) {
if (base64 == null) {
return null;
}
return new String(Base64.getDecoder().decode(base64), StandardCharsets.UTF_8);
}
/**
* 获取字符串的MD5哈希值
* @param str 字符串
* @return MD5哈希值
*/
public static String md5(String str) {
if (str == null) {
return null;
}
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest(str.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("MD5 algorithm not found", e);
}
}
/**
* 获取字符串的SHA-1哈希值
* @param str 字符串
* @return SHA-1哈希值
*/
public static String sha1(String str) {
if (str == null) {
return null;
}
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] hash = md.digest(str.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-1 algorithm not found", e);
}
}
/**
* 获取字符串的SHA-256哈希值
* @param str 字符串
* @return SHA-256哈希值
*/
public static String sha256(String str) {
if (str == null) {
return null;
}
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(str.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-256 algorithm not found", e);
}
}
/**
* 获取字符串的SHA-512哈希值
* @param str 字符串
* @return SHA-512哈希值
*/
public static String sha512(String str) {
if (str == null) {
return null;
}
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
byte[] hash = md.digest(str.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("SHA-512 algorithm not found", e);
}
}
/**
* 获取字符串的CRC32校验值
* @param str 字符串
* @return CRC32校验值
*/
public static long crc32(String str) {
if (str == null) {
return 0;
}
CRC32 crc32 = new CRC32();
crc32.update(str.getBytes(StandardCharsets.UTF_8));
return crc32.getValue();
}
/**
* 比较两个字符串(null安全)
* @param str1 字符串1
* @param str2 字符串2
* @return 比较结果
*/
public static int compare(String str1, String str2) {
if (str1 == str2) {
return 0;
}
if (str1 == null) {
return -1;
}
if (str2 == null) {
return 1;
}
return str1.compareTo(str2);
}
/**
* 比较两个字符串(忽略大小写,null安全)
* @param str1 字符串1
* @param str2 字符串2
* @return 比较结果
*/
public static int compareIgnoreCase(String str1, String str2) {
if (str1 == str2) {
return 0;
}
if (str1 == null) {
return -1;
}
if (str2 == null) {
return 1;
}
return str1.compareToIgnoreCase(str2);
}
/**
* 检查字符串是否以任意一个前缀开头
* @param str 字符串
* @param prefixes 前缀数组
* @return 是否以任意一个前缀开头
*/
public static boolean startsWithAny(String str, String... prefixes) {
if (isEmpty(str) || prefixes == null || prefixes.length == 0) {
return false;
}
for (String prefix : prefixes) {
if (str.startsWith(prefix)) {
return true;
}
}
return false;
}
/**
* 检查字符串是否以任意一个后缀结尾
* @param str 字符串
* @param suffixes 后缀数组
* @return 是否以任意一个后缀结尾
*/
public static boolean endsWithAny(String str, String... suffixes) {
if (isEmpty(str) || suffixes == null || suffixes.length == 0) {
return false;
}
for (String suffix : suffixes) {
if (str.endsWith(suffix)) {
return true;
}
}
return false;
}
/**
* 检查字符串是否包含任意一个子字符串
* @param str 字符串
* @param searchStrs 子字符串数组
* @return 是否包含任意一个子字符串
*/
public static boolean containsAny(String str, String... searchStrs) {
if (isEmpty(str) || searchStrs == null || searchStrs.length == 0) {
return false;
}
for (String searchStr : searchStrs) {
if (str.contains(searchStr)) {
return true;
}
}
return false;
}
/**
* 检查字符串是否包含所有子字符串
* @param str 字符串
* @param searchStrs 子字符串数组
* @return 是否包含所有子字符串
*/
public static boolean containsAll(String str, String... searchStrs) {
if (isEmpty(str) || searchStrs == null || searchStrs.length == 0) {
return false;
}
for (String searchStr : searchStrs) {
if (!str.contains(searchStr)) {
return false;
}
}
return true;
}
/**
* 获取字符串的第一个字符
* @param str 字符串
* @return 第一个字符,如果字符串为空则返回0
*/
public static char firstChar(String str) {
if (isEmpty(str)) {
return 0;
}
return str.charAt(0);
}
/**
* 获取字符串的最后一个字符
* @param str 字符串
* @return 最后一个字符,如果字符串为空则返回0
*/
public static char lastChar(String str) {
if (isEmpty(str)) {
return 0;
}
return str.charAt(str.length() - 1);
}
/**
* 获取字符串的第一个单词
* @param str 字符串
* @param separator 分隔符
* @return 第一个单词
*/
public static String firstWord(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = " ";
}
int index = str.indexOf(separator);
if (index == -1) {
return str;
}
return str.substring(0, index);
}
/**
* 获取字符串的最后一个单词
* @param str 字符串
* @param separator 分隔符
* @return 最后一个单词
*/
public static String lastWord(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = " ";
}
int index = str.lastIndexOf(separator);
if (index == -1) {
return str;
}
return str.substring(index + separator.length());
}
/**
* 获取字符串的字符数
* @param str 字符串
* @return 字符数
*/
public static int charCount(String str) {
if (isEmpty(str)) {
return 0;
}
return str.length();
}
/**
* 获取字符串的单词数
* @param str 字符串
* @param separator 分隔符
* @return 单词数
*/
public static int wordCount(String str, String separator) {
if (isEmpty(str)) {
return 0;
}
if (separator == null) {
separator = " ";
}
return str.split(separator).length;
}
/**
* 获取字符串的行数
* @param str 字符串
* @return 行数
*/
public static int lineCount(String str) {
if (isEmpty(str)) {
return 0;
}
return str.split("\\r?\\n").length;
}
/**
* 获取字符串的字节长度(UTF-8编码)
* @param str 字符串
* @return 字节长度
*/
public static int byteLength(String str) {
if (str == null) {
return 0;
}
return str.getBytes(StandardCharsets.UTF_8).length;
}
/**
* 获取字符串的字符出现次数
* @param str 字符串
* @param ch 字符
* @return 出现次数
*/
public static int charFrequency(String str, char ch) {
if (isEmpty(str)) {
return 0;
}
int count = 0;
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == ch) {
count++;
}
}
return count;
}
/**
* 获取字符串的子字符串出现次数
* @param str 字符串
* @param sub 子字符串
* @return 出现次数
*/
public static int substringFrequency(String str, String sub) {
if (isEmpty(str) || isEmpty(sub)) {
return 0;
}
int count = 0;
int idx = 0;
while ((idx = str.indexOf(sub, idx)) != -1) {
count++;
idx += sub.length();
}
return count;
}
/**
* 获取字符串中最长的单词
* @param str 字符串
* @param separator 分隔符
* @return 最长的单词
*/
public static String longestWord(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = " ";
}
String[] words = str.split(separator);
String longest = "";
for (String word : words) {
if (word.length() > longest.length()) {
longest = word;
}
}
return longest;
}
/**
* 获取字符串中最短的单词
* @param str 字符串
* @param separator 分隔符
* @return 最短的单词
*/
public static String shortestWord(String str, String separator) {
if (isEmpty(str)) {
return str;
}
if (separator == null) {
separator = " ";
}
String[] words = str.split(separator);
String shortest = null;
for (String word : words) {
if (shortest == null || word.length() < shortest.length()) {
shortest = word;
}
}
return shortest != null ? shortest : "";
}
/**
* 获取字符串的平均单词长度
* @param str 字符串
* @param separator 分隔符
* @return 平均单词长度
*/
public static double averageWordLength(String str, String separator) {
if (isEmpty(str)) {
return 0;
}
if (separator == null) {
separator = " ";
}
String[] words = str.split(separator);
if (words.length == 0) {
return 0;
}
int total = 0;
for (String word : words) {
total += word.length();
}
return (double) total / words.length;
}
/**
* 获取字符串中最常见的字符
* @param str 字符串
* @return 最常见的字符
*/
public static char mostCommonChar(String str) {
if (isEmpty(str)) {
return 0;
}
int[] counts = new int[Character.MAX_VALUE + 1];
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
counts[c]++;
}
char mostCommon = 0;
int maxCount = 0;
for (char c = 0; c < counts.length; c++) {
if (counts[c] > maxCount) {
maxCount = counts[c];
mostCommon = c;
}
}
return mostCommon;
}
/**
* 获取字符串中最不常见的字符
* @param str 字符串
* @return 最不常见的字符
*/
public static char leastCommonChar(String str) {
if (isEmpty(str)) {
return 0;
}
int[] counts = new int[Character.MAX_VALUE + 1];
Arrays.fill(counts, Integer.MAX_VALUE);
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (counts[c] == Integer.MAX_VALUE) {
counts[c] = 0;
}
counts[c]++;
}
char leastCommon = 0;
int minCount = Integer.MAX_VALUE;
for (char c = 0; c < counts.length; c++) {
if (counts[c] < minCount && counts[c] > 0) {
minCount = counts[c];
leastCommon = c;
}
}
return leastCommon;
}
/**
* 获取字符串中所有唯一字符
* @param str 字符串
* @return 唯一字符数组
*/
public static char[] uniqueChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
boolean[] exists = new boolean[Character.MAX_VALUE + 1];
for (int i = 0; i < str.length(); i++) {
exists[str.charAt(i)] = true;
}
int count = 0;
for (boolean exist : exists) {
if (exist) {
count++;
}
}
char[] result = new char[count];
int index = 0;
for (char c = 0; c < exists.length; c++) {
if (exists[c]) {
result[index++] = c;
}
}
return result;
}
/**
* 获取字符串中所有重复字符
* @param str 字符串
* @return 重复字符数组
*/
public static char[] duplicateChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
int[] counts = new int[Character.MAX_VALUE + 1];
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
counts[c]++;
}
int count = 0;
for (int cnt : counts) {
if (cnt > 1) {
count++;
}
}
char[] result = new char[count];
int index = 0;
for (char c = 0; c < counts.length; c++) {
if (counts[c] > 1) {
result[index++] = c;
}
}
return result;
}
/**
* 获取字符串中所有数字字符
* @param str 字符串
* @return 数字字符数组
*/
public static char[] digitChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isDigit(c)) {
sb.append(c);
}
}
return sb.toString().toCharArray();
}
/**
* 获取字符串中所有字母字符
* @param str 字符串
* @return 字母字符数组
*/
public static char[] letterChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isLetter(c)) {
sb.append(c);
}
}
return sb.toString().toCharArray();
}
/**
* 获取字符串中所有大写字母字符
* @param str 字符串
* @return 大写字母字符数组
*/
public static char[] uppercaseChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isUpperCase(c)) {
sb.append(c);
}
}
return sb.toString().toCharArray();
}
/**
* 获取字符串中所有小写字母字符
* @param str 字符串
* @return 小写字母字符数组
*/
public static char[] lowercaseChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isLowerCase(c)) {
sb.append(c);
}
}
return sb.toString().toCharArray();
}
/**
* 获取字符串中所有空白字符
* @param str 字符串
* @return 空白字符数组
*/
public static char[] whitespaceChars(String str) {
if (isEmpty(str)) {
return new char[0];
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (Character.isWhitespace(c)) {
sb.append(c);
}
}
return sb.toString().toCharArray();
}
}
使用建议
-
空值安全:所有方法都考虑了null值情况,避免NullPointerException
-
性能优化:对于频繁操作使用StringBuilder实现
-
编码规范:默认使用UTF-8编码处理字节转换
-
正则表达式:复杂匹配使用预编译Pattern提升性能
实际应用场景
-
数据清洗:去除多余空白、格式化不规范数据
-
输入验证:检查用户输入的格式和内容
-
文本分析:统计词频、提取关键信息
-
安全处理:转义特殊字符、生成安全内容
-
数据转换:不同格式间的相互转换
总结
这个StringUtils工具类集成了Java字符串处理的精华,可以显著提高开发效率。它既包含了Apache Commons Lang等库中的常用方法,也添加了许多实用的扩展功能。在实际项目中,开发者可以直接使用或根据需求进行扩展。


被折叠的 条评论
为什么被折叠?



