Java中公用字符串工具类拿走、直接用
概述
字符串操作是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等库中的常用方法,也添加了许多实用的扩展功能。在实际项目中,开发者可以直接使用或根据需求进行扩展。