我不认为它可以改进。简短的回答是,因为搜索最后一个索引是一个简单的操作,所以可以使用快速算法(直接在 String 类中!)来实现,而正则表达式很难做到这么快。
如您所见,第二次访问 String 的成本不能少:它只是新 String 的初始化。
如果有直接在 String 类中实现的专用方法,可能会更快。
如果您想了解更多细节,您可以自己查看 JDK 中的代码。为了您的方便,复制到这里。
以下代码是我的JDK中lastIndexOf()方法的实现:
public int lastIndexOf(int ch, int fromIndex) {
int min = offset;
char v[] = value;
int i = offset + ((fromIndex >= count) ? count - 1 : fromIndex);
if (ch < Character.MIN_SUPPLEMENTARY_CODE_POINT) {
// handle most cases here (ch is a BMP code point or a
// negative value (invalid code point))
for (; i >= min ; i--) {
if (v[i] == ch) {
return i - offset;
}
}
return -1;
}
int max = offset + count;
if (ch <= Character.MAX_CODE_POINT) {
// handle supplementary characters here
char[] surrogates = Character.toChars(ch);
for (; i >= min; i--) {
if (v[i] == surrogates[0]) {
if (i + 1 == max) {
break;
}
if (v[i+1] == surrogates[1]) {
return i - offset;
}
}
}
}
return -1;
}
直接在 String 类中实现,它可以访问其私有成员:
/** The value is used for character storage. */
private final char value[];
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
它不适用于子字符串。
同时,Java 中的 substring 方法非常快,因为它不会创建一个新的 char 数组,而是简单地创建一个新的 String 对象,改变偏移量和计数:
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > count) {
throw new StringIndexOutOfBoundsException(endIndex);
}
if (beginIndex > endIndex) {
throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
}
return ((beginIndex == 0) && (endIndex == count)) ? this :
new String(offset + beginIndex, endIndex - beginIndex, value);
}
// Package private constructor which shares value array for speed.
String(int offset, int count, char value[]) {
this.value = value;
this.offset = offset;
this.count = count;
}