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

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チェックする必要がありますが、ハッシュベースのアプローチでは、ハッシュ値を1回だけ計算する必要があり、既知のすべてのハッシュ値に対してバイナリ検索を実行できます。String.equals()

于 2012-09-18T10:25:13.413 に答える