任意字符串的UriMatcher模式,而不是URI

时间:2012-09-18 09:43:41

标签: android string-comparison

我不禁注意到在解析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模式,它会很简洁。)

到目前为止,我一直在寻找正则表达式,但我不确定我是否能够满足我的需求(我想要一个开关 - 案例样式测试),当然还有常规的字符串比较,如图所示上面的例子。

干杯,    - dbm

2 个答案:

答案 0 :(得分:1)

使用SparseArray

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

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

           case 1:
             break
        }

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

答案 1 :(得分:1)

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

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()归结为比较字符串的所有字符,而基于散列的方法只需要计算一次哈希值,并且可以对所有已知哈希进行二进制搜索价值观。