org.apache.commons.lang3.StringUtils 原始碼解讀彙總
阿新 • • 發佈:2020-07-05
一、背景
不管是公司的專案,還是個人的日常練習,都會使用org.apache.commons.lang3.StringUtils 這個String工具類,究其原因,是太好用了,而且太全了。比如判斷是否為空,擷取,拼接之類的。一直沒有仔細的看過它的原始碼,今天我就研究一番,同時作為我“閱讀原始碼”路上的第一步。
//todo
什麼是CharSequence
//todo
‘’,null,‘ ’區別
二、常用API
注:本次是基於commons-lang3-3.8.1 進行閱讀分析總結的,其他版本與此相差不多。
2.1、Empty
2.1.1、isEmpty:檢查字串是 "" 或 null
//原始碼 public static boolean isEmpty(final CharSequence cs) { return cs == null || cs.length() == 0; }
@Test public void isEmpty_Test() { //true StringUtils.isEmpty(null); //true StringUtils.isEmpty(""); //false StringUtils.isEmpty(" "); //false StringUtils.isEmpty("bob");//false StringUtils.isEmpty(" bob "); }
2.1.2、isNotEmpty:與isEmpty正好相反,判斷不為""且不為null
//原始碼 public static boolean isNotEmpty(final CharSequence cs) { return !isEmpty(cs); }
@Test public void isNotEmpty_Test() { //false StringUtils.isNotEmpty(null); //false StringUtils.isNotEmpty("");//true StringUtils.isNotEmpty(" "); //true StringUtils.isNotEmpty("bob"); //true StringUtils.isNotEmpty(" bob "); }
2.1.3、isAnyEmpty
2.1.4、isNoneEmpty
2.1.5、isAllEmpty
2.2、Blank
2.2.1、isBlank:檢查一個字串是 "",或null,或只有空格
與isEmpty相比,對於“ ”,isEmpty(" ") =false,isBlank(" ") =true,
//原始碼 public static boolean isBlank(final CharSequence cs) { int strLen; if (cs == null || (strLen = cs.length()) == 0) { return true; } for (int i = 0; i < strLen; i++) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; }
@Test public void isBlank_Test() { //true StringUtils.isBlank(null); //true StringUtils.isBlank(""); //true StringUtils.isBlank(" "); //false StringUtils.isBlank("bob"); //false StringUtils.isBlank(" bob "); }
2.2.2、isNotBlank:檢查一個字串不是 "",且不是null,且不只有空格
@Test public void isNotBlank_Test() { //false StringUtils.isNotBlank(null); //false StringUtils.isNotBlank(""); //false StringUtils.isNotBlank(" "); //true StringUtils.isNotBlank("bob"); //true StringUtils.isNotBlank(" bob "); }
2.2.3、isAnyBlank
2.2.4、isNoneBlank
2.2.5、isAllBlank
2.3、Trim
2.3.1、trim:移除字串兩端的空字串
//原始碼 public static String trim(final String str) { return str == null ? null : str.trim(); }
@Test public void trim_Test() { //null StringUtils.trim(null); //"" StringUtils.trim(""); //"" StringUtils.trim(" "); //"abc" StringUtils.trim("abc"); //"abc" StringUtils.trim(" abc "); }
2.3.2、trimToNull:trim之後,用isEmpty進行了判斷,如果true返回null,否則返回trim後的值
//原始碼 public static String trimToNull(final String str) { final String ts = trim(str); return isEmpty(ts) ? null : ts; }
StringUtils.trimToNull(null) = null StringUtils.trimToNull("") = null StringUtils.trimToNull(" ") = null StringUtils.trimToNull("abc") = "abc" StringUtils.trimToNull(" abc ") = "abc"
2.3.3、trimToEmpty:如果為null,返回“”,否則返回trim後的值
//原始碼 public static String trimToEmpty(final String str) { return str == null ? EMPTY : str.trim(); }
StringUtils.trimToEmpty(null) = "" StringUtils.trimToEmpty("") = "" StringUtils.trimToEmpty(" ") = "" StringUtils.trimToEmpty("abc") = "abc" StringUtils.trimToEmpty(" abc ") = "abc"
2.4、Trim
2.4.1、truncate:字串擷取,從索引為0處擷取,擷取固定的長度
//原始碼 public static String truncate(final String str, final int maxWidth) { return truncate(str, 0, maxWidth); }
StringUtils.truncate(null, 0) = null StringUtils.truncate(null, 2) = null StringUtils.truncate("", 4) = "" StringUtils.truncate("abcdefg", 4) = "abcd" StringUtils.truncate("abcdefg", 6) = "abcdef" StringUtils.truncate("abcdefg", 7) = "abcdefg" StringUtils.truncate("abcdefg", 8) = "abcdefg" StringUtils.truncate("abcdefg", -1) = throws an IllegalArgumentException
可以看到,對於起始擷取索引,擷取長度為負數時,直接報異常;然後被擷取字串為null時,返回null;擷取索引大於字串長度時,返回“”。
//原始碼 public static String truncate(final String str, final int offset, final int maxWidth) { if (offset < 0) { throw new IllegalArgumentException("offset cannot be negative"); } if (maxWidth < 0) { throw new IllegalArgumentException("maxWith cannot be negative"); } if (str == null) { return null; } if (offset > str.length()) { return EMPTY; } if (str.length() > maxWidth) { final int ix = offset + maxWidth > str.length() ? str.length() : offset + maxWidth; return str.substring(offset, ix); } return str.substring(offset); }
StringUtils.truncate(null, 0, 0) = null StringUtils.truncate(null, 2, 4) = null StringUtils.truncate("", 0, 10) = "" StringUtils.truncate("", 2, 10) = "" StringUtils.truncate("abcdefghij", 0, 3) = "abc" StringUtils.truncate("abcdefghij", 5, 6) = "fghij" StringUtils.truncate("raspberry peach", 10, 15) = "peach" StringUtils.truncate("abcdefghijklmno", 0, 10) = "abcdefghij" StringUtils.truncate("abcdefghijklmno", -1, 10) = throws an IllegalArgumentException StringUtils.truncate("abcdefghijklmno", Integer.MIN_VALUE, 10) = "abcdefghij" StringUtils.truncate("abcdefghijklmno", Integer.MIN_VALUE, Integer.MAX_VALUE) = "abcdefghijklmno" StringUtils.truncate("abcdefghijklmno", 0, Integer.MAX_VALUE) = "abcdefghijklmno" StringUtils.truncate("abcdefghijklmno", 1, 10) = "bcdefghijk" StringUtils.truncate("abcdefghijklmno", 2, 10) = "cdefghijkl" StringUtils.truncate("abcdefghijklmno", 3, 10) = "defghijklm" StringUtils.truncate("abcdefghijklmno", 4, 10) = "efghijklmn" StringUtils.truncate("abcdefghijklmno", 5, 10) = "fghijklmno" StringUtils.truncate("abcdefghijklmno", 5, 5) = "fghij" StringUtils.truncate("abcdefghijklmno", 5, 3) = "fgh" StringUtils.truncate("abcdefghijklmno", 10, 3) = "klm" StringUtils.truncate("abcdefghijklmno", 10, Integer.MAX_VALUE) = "klmno" StringUtils.truncate("abcdefghijklmno", 13, 1) = "n" StringUtils.truncate("abcdefghijklmno", 13, Integer.MAX_VALUE) = "no" StringUtils.truncate("abcdefghijklmno", 14, 1) = "o" StringUtils.truncate("abcdefghijklmno", 14, Integer.MAX_VALUE) = "o" StringUtils.truncate("abcdefghijklmno", 15, 1) = "" StringUtils.truncate("abcdefghijklmno", 15, Integer.MAX_VALUE) = "" StringUtils.truncate("abcdefghijklmno", Integer.MAX_VALUE, Integer.MAX_VALUE) = "" StringUtils.truncate("abcdefghij", 3, -1) = throws an IllegalArgumentException StringUtils.truncate("abcdefghij", -2, 4) = throws an IllegalArgumentException