0

我不禁注意到我在解析 Android 中定义明确的 XML 文件时使用了很多字符串比较(带有XmlPullParser.

到目前为止,它通常看起来像这样(有点简化):

...
tag = parser.getName().toLowerCase();
if ("tag1".equals(tag)) {
    // Do something with the state machine
}
else if ("tag2".equals(tag)) {
    // Do something else with the state machine
}

...

else if ("tag23".equals(tag)) {
    // Do something more with the state machine
}

相反,我想要的是这样的(StringMatcher 对我来说是假设的快乐制造者):

private static final StringMatcher tagMatcher = new StringMatcher(StringMatcher.NO_MATCH);

static {
    tagMatcher.addString("tag1", 1);
    tagMatcher.addString("tag2", 2);
    ....
    tagMatcher.addString("tag23", 23);
}

...

tag = parser.getName().toLowerCase();
switch (tagMatcher.match(tag)) {
    case 1:
        // Do something with the state machine
        break;
    case 2:
        // Do something else with the state machine
        break;
    ...
    case 23:
        // Do something more with the state machine
        break;
    default:
        Log.e("PARSER", "Unexpected tag: " + tag);
        break;
}

如您所见,我希望将一种UriMatcher模式应用于我的 XML 文件标签。你们中有人知道我可以在 Android 中使用这样的类吗?任何其他对字符串的快速过滤也可以(不过,如果可以重用 UriMatcher 模式,它会很整洁)。

到目前为止,我一直在研究正则表达式,但我不确定我是否能满足我的需要(我想要一个 switch - case 样式测试),当然还有上面示例中所示的常规字符串比较。

干杯,--dbm

4

2 回答 2

1

用一个SparseArray

 static{
        tagmatcher.append(0, "tag1");
        tagmatcher.append(1, "tag2");
    }

  switch(tagmatcher.keyAt(tagmatcher.indexOfValue(tag))){
           case 0:
             break;

           case 1:
             break
        }

但是如果你要添加连续的索引,你总是可以使用 ArrayList

于 2012-09-18T10:03:34.217 回答
1

您可以使用 aHashMap因为它不需要遍历整个数组来查找匹配值

private static final HashMap<String, Integer> tagMatcher =
        new HashMap<String, Integer>();

static {
    tagMatcher.put("tag1", 1);
    tagMatcher.put("tag2", 2);
    tagMatcher.put("tag23", 23);
}

private void parse (String node) {
    Integer value = tagMatcher.get(node);
    int match = value != null ? value.intValue() : 0;
    switch (match) {
        case 1:
            // etc
            break;
        case 0: // no match
            break;
    }
}

或者您可以使用SparseIntArray相同的哈希方法。这里的优势是您不需要将其int放入Integer其中会产生轻微的速度/内存优势。

private static final SparseIntArray tagMatcher2 = new SparseIntArray();
private static void put(String key, int value) {
    tagMatcher2.put(key.hashCode(), value);
}
private static int get(String key) {
    return tagMatcher2.get(key.hashCode());
}
static {
    put("tag1", 1);
    put("tag2", 2);
    put("tag23", 23);
}

private void parse2 (String node) {
    switch (get(node)) {
        case 1:
            // etc
            break;
        case 0: // no match
            break;
    }
}

这是进行二进制搜索,而不是像这样迭代整个事情SparseArray#indexOfValue(t)。请注意,这种方法可能会发生哈希冲突。

我认为使用这样的方法比if (equals) else if (equals)进行大量比较的长链更快。该if .. else if方法需要检查String.equals()每次归结为比较字符串的所有字符,而基于哈希的方法只需要计算一次哈希值,然后可以对所有已知的哈希值进行二进制搜索。

于 2012-09-18T10:25:13.413 回答