不积跬步,无以至千里。不积小流,无以成江海。

我们常用的StringUtils工具类org.apache.commons.lang3.StringUtils 与 org.springframework.util.StringUtils

他们提供的Split方法有差别,导致今天程序出现问题时费了点时间才发现问题。特意写测试对比了两个方法,以免以后再掉坑里。

实现方式对比

首先是 org.apache.commons.lang3.StringUtils#split 的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* <p>Splits the provided text into an array, separators specified.
* This is an alternative to using StringTokenizer.</p>
*
* <p>The separator is not included in the returned String array.
* Adjacent separators are treated as one separator.
* For more control over the split use the StrTokenizer class.</p>
*
* <p>A {@code null} input String returns {@code null}.
* A {@code null} separatorChars splits on whitespace.</p>
*
* <pre>
* StringUtils.split(null, *) = null
* StringUtils.split("", *) = []
* StringUtils.split("abc def", null) = ["abc", "def"]
* StringUtils.split("abc def", " ") = ["abc", "def"]
* StringUtils.split("abc def", " ") = ["abc", "def"]
* StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
* </pre>
*
* @param str the String to parse, may be null
* @param separatorChars the characters used as the delimiters,
* {@code null} splits on whitespace
* @return an array of parsed Strings, {@code null} if null String input
*/
public static String[] split(final String str, final String separatorChars) {
return splitWorker(str, separatorChars, -1, false);
}

在上面的注释中已经给出了一些示例

org.springframework.util.StringUtils#split的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
* Split a {@code String} at the first occurrence of the delimiter.
* Does not include the delimiter in the result.
* @param toSplit the string to split (potentially {@code null} or empty)
* @param delimiter to split the string up with (potentially {@code null} or empty)
* @return a two element array with index 0 being before the delimiter, and
* index 1 being after the delimiter (neither element includes the delimiter);
* or {@code null} if the delimiter wasn't found in the given input {@code String}
*/
@Nullable
public static String[] split(@Nullable String toSplit, @Nullable String delimiter) {
if (!hasLength(toSplit) || !hasLength(delimiter)) {
return null;
}
int offset = toSplit.indexOf(delimiter);
if (offset < 0) {
return null;
}

String beforeDelimiter = toSplit.substring(0, offset);
String afterDelimiter = toSplit.substring(offset + delimiter.length());
return new String[] {beforeDelimiter, afterDelimiter};
}
/**
* Check that the given {@code String} is neither {@code null} nor of length 0.
* <p>Note: this method returns {@code true} for a {@code String} that
* purely consists of whitespace.
* @param str the {@code String} to check (may be {@code null})
* @return {@code true} if the {@code String} is not {@code null} and has length
* @see #hasLength(CharSequence)
* @see #hasText(String)
*/
public static boolean hasLength(@Nullable String str) {
return (str != null && !str.isEmpty());
}

测试对比

下面通过跑测试对比如下:

参数1 参数2 org.apache.commons.lang3.StringUtils#split org.springframework.util.StringUtils#split
null null null null
“1,2” “,” String[1]={“1,2”} null
null “,” Null null
“1,2,3” “,” String[3]={“1”,”2”,”3”} String[3]={“1”,”2”,”3”}
“1,2,3” “:” String[1]={“1,2,3”} null
“” “,” String[0]={} null
“1” “,” String[1]={“1”} null

通过对比,org.apache.commons.lang3.StringUtils#split 优势明显,不会随便就抛出空指针异常,因此今后最好使用 org.apache.commons.lang3.StringUtils#split这个方法,可以避免一些无端的异常。