找到网址路径最后一部分的最快方法是什么?

时间:2016-01-16 16:06:12

标签: java regex

我有一个网址,例如:

" HTTP:/www.someco.com/news/2016-01-03/waterloo-station"

网址永远不会包含查询字符串。

提取String"滑铁卢"最简洁的方法是什么? ?

当然我可以使用以下代码:

url.substring(url.lastIndexOf('/') + 1))

但我并不完全满意,因为它必须执行搜索最后一个索引然后获取子字符串。我想知道是否有更好的方法(使用正则表达式?)在一步中获得相同的结果。

当然,执行数十亿次后解决方案应该会快得多。

1 个答案:

答案 0 :(得分:2)

我不认为它可以改进。简短的回答是,因为搜索最后一个索引是一个简单的操作,它可以用快速算法(直接在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;

它不适用于子串。 同时,substring方法在Java中非常快,因为它不会创建一个新的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;
}