StringUtils类在操作字符串是安全的,不会报空指针异常,也正因此,在操作字符串时使用StringUtils相比使用原生的String会更加安全。
StringUtils提供常用的判断空字符串有两个方法:isEmpty和isBlank,这两者的有何区别呢,直接看源码:
// isEmpty
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
// isBlank
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if ((Character.isWhitespace(str.charAt(i)) == false)) {
return false;
}
}
return true;
}
// isNotEmpty
public static boolean isNotEmpty(String str) {
return !StringUtils.isEmpty(str);
}
// isNotBlank
public static boolean isNotBlank(String str) {
return !StringUtils.isBlank(str);
}
从源码上看一目了然(null值两者的判断逻辑是一致的,都为true):
isBlank:判断更严谨,包含的有空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
isEmpty:包含是空串("")和null值,不包含空白符;
isNotBlank和isNotEmpty都是取反的,不再赘述;
首字母大小写转换
// 空字符串(包括空格、制表符等)原样输出
// 首字母大写
public static String capitalize(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
return new StrBuilder(strLen)
.append(Character.toTitleCase(str.charAt(0)))
.append(str.substring(1))
.toString();
}
// 首字母小写
public static String uncapitalize(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
return new StrBuilder(strLen)
.append(Character.toLowerCase(str.charAt(0)))
.append(str.substring(1))
.toString();
}
其它方法都差不多,就不展示源码了,有兴趣的朋友自己去查看下;
// upperCase--全部转大写
StringUtils.upperCase(null); // null
StringUtils.upperCase("china"); // CHINA (全部转为大写)
StringUtils.upperCase("china", Locale.ENGLISH); // CHINA (按照指定规则转换为大写)
// lowerCase--全部转小写
StringUtils.lowerCase(null); // null
StringUtils.lowerCase("CHINA"); // china (全部转换为小写)
StringUtils.lowerCase("CHINA", Locale.ENGLISH); // china (按照指定转换规则转换为小写)
// swapCase--大小写互换
StringUtils.swapCase(null); // null
StringUtils.swapCase("chINA"); // CHina
// 判断字符串是否全部是大写或小写(空或空白符均为false)
StringUtils.isAllUpperCase(null); // false
StringUtils.isAllUpperCase(""); // false
StringUtils.isAllUpperCase(" "); // false
StringUtils.isAllUpperCase("CHINA"); // true
StringUtils.isAllLowerCase(null); // false
StringUtils.isAllLowerCase(""); // false
StringUtils.isAllLowerCase(" "); // false
StringUtils.isAllLowerCase("china"); // true
常用的方法有:
// 移除单个字符
StringUtils.remove(String str, char remove)
// 移除单个字符
StringUtils.remove(String str, String remove);
// 移除开头/结尾匹配的字符序列
StringUtils.removeStart(String str, String remove);
StringUtils.removeStartIgnoreCase(String str, String remove);
StringUtils.removeEnd(String str, String remove);
StringUtils.removeEndIgnoreCase(String str, String remove);
1. deleteWhitespace(String str) 先看源码的----去除所有空白符
// 去除字符串中所有的空白符
public static String deleteWhitespace(String str) {
if (isEmpty(str)) {
return str;
}
int sz = str.length();
char[] chs = new char[sz];
int count = 0;
for (int i = 0; i < sz; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
chs[count++] = str.charAt(i);
}
}
if (count == sz) {
return str;
}
return new String(chs, 0, count);
}
2. trim相关方法
trimToEmpty、trimToNull是trim基础上进行返回值的扩展
// 去除前后空格,如果为null,返回null
StringUtils.trim(" ab c ");// ab c
// 源码
public static String trim(String str) {
return str == null ? null : str.trim();
}
// 先trim,如果为null,返回空字符串
StringUtils.trimToEmpty(null);// ""
// 源码
public static String trimToEmpty(String str) {
return str == null ? EMPTY : str.trim();
}
// 先trim,如果为空,返回null
StringUtils.trimToNull(null);// null
// 源码
public static String trimToNull(String str) {
String ts = trim(str);
return isEmpty(ts) ? null : ts;
}
3. strip最常用的一个方法就是去掉前后面匹配的符号,这个应用广泛
StringUtils.strip("[asdf]", "[]"); //asdf
需要注意的是,若被替换的字符串为null,或者被替换的字符或字符序列为null,又或者替换的字符或字符序列为null,那 此次替换都会被忽略,返回原字符串;
// 替换单个字符或字符序列
replace(String text, String searchString, String replacement);
replace(String text, String searchString, String replacement, int max);//max是指替换最大次数,0:不替换,-1:全部替换
replaceChars(String str, char searchChar, char replaceChar);
replaceChars(String str, String searchChars, String replaceChars);
// 只会替换一次,后面即使匹配也不替换
replaceOnce(String text, String searchString, String replacement);
// 指定位置进行字符序列替换,从start索引处开始(包含)到end-1索引处为止进行替换
overlay(String str,String overlay,int start,int end);
// 可以同时替换多个字符序列,一一对应但被替换和替换的字符序列的个数应该对应,否则会报IllegalArgumentException
replaceEach(String text, String[] searchList, String[] replacementList);
StringUtils.replaceEach("test", new String[] { "t", "e" }, new String[] { "T", "E" }); // TEsT
StringUtils.replaceEach("test", null, new String[] { "T", "E" }); // test (存在null,不进行替换)
// IllegalArgumentException (被替换和替换的个数不对应)
StringUtils.replaceEach("test", new String[] { "t", "e" }, new String[] { "T", "E", "X" });
// 循环替换--了解即可
replaceEachRepeatedly(String text, String[] searchList, String[]replacementList);
StringUtils.replaceEachRepeatedly("test", new String[] { "e", "E" }, new String[] { "E", "Y" }); // tYst (e被替换为E,E又被替换为Y)
// 直接反转
StringUtils.reverse("abcdef"); // fedcba
// 根据分隔符进行反转
StringUtils.reverseDelimited("a.b.c.d.e.f", '.'); // f.e.d.c.b.a
这个功能很好用,也需要灵活使用;
基本规则:从左到右下标默认是从0开始的,从右到左是从-1开始
1. substring(String str,int start)
// 当指定的截取位置为非负数时,则从左往右开始截取
StringUtils.substring("abcd", 1); //bcd
// 但当索引值为负数时,则从右往左截取,注意此时右侧第一位为-1:
StringUtils.substring("abcd", -2); //cd
2. substring(String str,int start, int end)
// 指定了起始位置和结束位置,则从起始位置开始截取到结束位置(但不包含结束位置)
StringUtils.substring("abcd", 1,3); //bc
// 特别注意负数是从右到左算的
StringUtils.substring("abcdef", 1,-1);//bcde
3. 根据指定的分隔符进行截取
// 从分隔符第一次出现的位置向后或向前截取
StringUtils.substringAfter("abc,de,fg", ","); //de,fg
StringUtils.substringBefore("abc,de,fg", ","); //abc
// 从分隔符最后一次出现的位置向后或向前截取
StringUtils.substringAfterLast("abc,de,fg", ","); //fg
StringUtils.substringBeforeLast("abc,de,fg", ","); //abc,de
// 截取指定标记字符串之间的字符序列
StringUtils.substringBetween("aBcdefBef", "B");// cdef
着重强调一个函数,容易搞混,containsAny(CharSequence cs, CharSequence searchChars)
这个方法是后面只要含有前面字符串中任意一个字符即为true,如果是用数字匹配的话,就不要用这个,后面搜索的字符 串会给打散为字符数组进行比对,看源码
public static boolean containsAny(String str, String searchChars) {
if (searchChars == null) {
return false;
}
return containsAny(str, searchChars.toCharArray());//转化为字符数组
}
public static boolean containsAny(String str, char[] searchChars) {
if (isEmpty(str) || ArrayUtils.isEmpty(searchChars)) {
return false;
}
int csLength = str.length();
int searchLength = searchChars.length;
int csLast = csLength - 1;
int searchLast = searchLength - 1;
for (int i = 0; i < csLength; i++) {
char ch = str.charAt(i);
for (int j = 0; j < searchLength; j++) {
if (searchChars[j] == ch) {
if (CharUtils.isHighSurrogate(ch)) {
if (j == searchLast) {
// missing low surrogate, fine, like String.indexOf(String)
return true;
}
if (i < csLast && searchChars[j + 1] == str.charAt(i + 1)) {
return true;
}
} else {
// ch is in the Basic Multilingual Plane
return true;
}
}
}
}
return false;
}
判断字符串中的字符是否都是出自所指定的字符数组或字符串 StringUtils.containsOnly(str, validChars);
需要注意的是:前面的字符是否都出自后面的参数中,也是拆为数组来比较,看官方API示例:
StringUtils.containsOnly(null, *) = false
StringUtils.containsOnly(*, null) = false
StringUtils.containsOnly("", *) = true
StringUtils.containsOnly("ab", "") = false
StringUtils.containsOnly("abab", "abc") = true
StringUtils.containsOnly("ab1", "abc") = false
StringUtils.containsOnly("abz", "abc") = false
其余的方法跟String的方法基本一致的
// contains
StringUtils.contains(null, *) = false
StringUtils.contains(*, null) = false
StringUtils.contains("", "") = true
StringUtils.contains("abc", 'a') = true
StringUtils.contains("abc", "") = true
StringUtils.contains("abc", "z") = false
// containsNone
StringUtils.containsNone("ab1", "xyz") = true
StringUtils.containsNone("abz", "xyz") = false
// startsWith
StringUtils.startsWith("abcdef", "abc") = true
这个跟String方法差不多,直接看示例吧
// 1.返回searchChar在字符串中第一次出现的位置,如果searchChar没有在字符串中出现,则返回-1
StringUtils.indexOf("sdfsfsfdsf","4");//结果是-1
StringUtils.indexOf("sdfsfsfdsf","f");//结果是2
// 2.查找searchChar在字符串中最后一次出现的索引
StringUtils.lastIndexOf("aFkyk","k");//结果是4
StringUtils.lastIndexOf("aFkyk","");//结果是1
// 3.找出字符数组searChars第一次出现在字符串中的位置
StringUtils.indexOfAny("sdsfhhl0","f");//结果是3
// 4.找出字符串中不在字符数组searchars中的第一个字符出现的位置(从0位开始) 如果都在,返回-1
StringUtils.indexOfAnyBut("sdsfhhl0","h");//结果是0
StringUtils.indexOfAnyBut("sdsfhhl0","s");//结果是1
StringUtils.indexOfAnyBut("aa","aa");//结果是-1
// 5.统计参数1和参数2开始部分共有的字符个数
StringUtils.indexOfDifference("sdsfdsf","s");//结果是1
// 6.去掉参数2在参数1开始部分共有的字符串
StringUtils.difference("好好学习天天向上","好好天天");//结果是:天天