2009-08-23 5 views
0

私は、国名とコードのキー/値のペアを含むjavaプロパティファイルを持っています。このファイルの内容をListやHashMapのようなコレクションにロードします。Javaでコレクションを検索する

次に、ユーザーがテキストボックスに 'Aus'と入力して[送信]をクリックすると、ユーザーが国を検索できるようにしたいのですが、次にキー/値のペアを含むコレクションを検索したい国コード/名前(例:AUS => Australia)を入力し、一致するものが見つかった国を返します。

これは、コレクションの要素をループしてcharAt()を使用する以外の方法がありますか?

答えて

1

)の方法であるあなたには、いくつかの重いに移動する場合を除き、文字列をループとは対照的に、あなたはstartsWithを使用することができます砲兵Luceneのような砲兵。

+0

です。ありがとうございました。私は 'contains'を思い出しました –

+0

Gah!最初に見つかった –

+1

もちろん、 "オーストラリア" .contains( "AUS") 'はfalseを返します。 –

1

Luceneのようなものでコレクションのインデックスを作成するのではない場合は、すべての要素をループして手動でチェックする必要があります。代わり

String userText = ... 
for (Map.Entry<String, String> entry : map) { 
    boolean entryMatches = entry.getKey().startsWith(userText); 
    ... 

または使用する正規表現::String.contains(とループ

Pattern pattern = Pattern.compile(userText); 

for (Map.Entry<String, String> entry : map) { 
    boolean entryMatches = pattern.matcher(entry.getKey()).find(); 
    ... 
-1

リストはメモリにロードするのに十分小さいので、静的メソッドjava.util.Collections.binarySearch()を使用してソートしてからバイナリ検索を行います。これは、インデックスを返し、正確な文字列がリストにあるかどうかに関係なく機能します(ただし、それが負の数を返さない場合はチェックしてください)。次に、そのインデックスから開始して、その接頭辞を持つすべての文字列を見つけるための順方向の反復だけを行います。素晴らしい副作用として、結果の出力はアルファベット順になります。

大文字小文字を区別しないようにするには、リストをロードするときには小文字に変換し、冒頭に小文字に変換してから検索してください。

+0

これはナンセンスです!あなたは "AUS"上で 'binarySearch'を実行し、任意のJavaコレクション内で" Australia "を見つけることはできません –

+0

明らかに、リストがロードされ、各リクエストではなく1回だけソートされたと仮定しています! –

+0

@oxbox_lakes:大文字小文字を区別しないようにする方法を説明しました。私は "aus"を探して "オーストラリア"を探しています。 –

3

パフォーマンスが重要な場合は、TreeSetまたはTreeMapを使用して国名を保持することができます。また、指定した文字列で始まる国を識別するために、次のように使用できます。

NavigableMap<String, String> countries = new TreeMap<String, String>(); 
countries.put("australia", "Australia"); 
... 

String userText = ... 
String tmp = userText.toLower(); 
List<String> hits = new ArrayList<String>(); 
Map.Entry<String, String> entry = countries.ceilingEntry(tmp); 
while (entry != null && entry.getKey().startsWith(tmp)) { 
    hits.add(entry.getValue()); 
    entry = map.higherEntry(entry.getKey()); 
} 
// hits now contains all country names starting with the value of `userText`, 
// ignoring differences in letter case. 

これは、Nは、国の数であるO(logN)です。これと対照的に、コレクションの線形検索はO(N)

+0

+1非常に完璧です。もちろんmap.higherEntry()はO(1)であると仮定しています...それは? –

+0

O(1)またはO(logn)にすることができます。いずれの場合も、higherEntry()を呼び出しても複雑さは変わりません。 higherEntry()が呼び出される回数を考慮すると、複雑になります。それは接頭文字列の長さとNの関数です。 –

関連する問題