不经常看源码的人很难读懂源码,就算是很简单的逻辑,源码里面写法也能秀到你头皮发麻,但是从各方面来说,已经是最佳实践了.
看源码最深的体会就是:越是稳定,高效的代码,其语法和逻辑越是贴近计算机的思维,当然对于人来说更加难懂,因此看源码是逆天而行哈哈哈.
因此.作为经常写bug折腾自己的菜鸟,在一家看似养老偶尔也能忙成狗的小公司,觉得经常阅读学习源码,有助于锻炼逻辑思维,也能提升代码质量.
今天看的源码是String里面的startsWith和endsWith两个方法:
不看不知道,一看吓一跳,这endsWith居然调用的startsWith,顿时觉得自己太native了
public boolean endsWith(String suffix) {
return startsWith(suffix, value.length - suffix.value.length);
}
然后转到startsWith:
/**
* Tests if the substring of this string beginning at the
* specified index starts with the specified prefix.
*
* @param prefix the prefix.
* @param toffset where to begin looking in this string.
* @return {@code true} if the character sequence represented by the
* argument is a prefix of the substring of this object starting
* at index {@code toffset}; {@code false} otherwise.
* The result is {@code false} if {@code toffset} is
* negative or greater than the length of this
* {@code String} object; otherwise the result is the same
* as the result of the expression
* <pre>
* this.substring(toffset).startsWith(prefix)
* </pre>
*/
public boolean startsWith(String prefix, int toffset) {
char ta[] = value;
int to = toffset;
char pa[] = prefix.value;
int po = 0;
int pc = prefix.value.length;
// Note: toffset might be near -1>>>1.
if ((toffset < 0) || (toffset > value.length - pc)) {
return false;
}
while (--pc >= 0) {
if (ta[to++] != pa[po++]) {
return false;
}
}
return true;
}
public boolean startsWith(String prefix) {
return startsWith(prefix, 0);
}
原来startsWith早就预留了 一个参数toffset,注释里面也说了,是从这个位置开始匹配,然后endsWith就相当于this.substring(toffset).startsWith(prefix),
将toffset设为value.length - suffix.value.length就可以了,而我们最常用的startsWith相当于从0位置开始匹配,这抽象恰到好处
看到startsWith方法后面还是挨个比对char,顿时松了一口气,看来没有更骚的操作了哈哈哈
然后手痒痒,按照源码思维自己写了下,那一坨非空校验是电商狗的真实写照了:
public static boolean startsWith(String str, String prefix, int startPos) {
if (str == null || prefix == null || startPos < 0) {
return false;
}
char[] strChars = str.toCharArray(), preChars = prefix.toCharArray();
int strLen = strChars.length, preLen = preChars.length;
if (startPos + preLen > strLen) {
return false;
}
int idx = 0;
while (idx < preLen) {
if (strChars[startPos + idx] != preChars[idx]) {
return false;
}
idx++;
}
return true;
}
public static boolean endsWith(String str, String suffix) {
if (str == null || suffix == null) {
return false;
}
return startsWith(str, suffix, str.length() - suffix.length());
}