文字列をキーとして持つツリーマップがあります。キーが文字列検索で始まるすべての値を取得したいと思います。
ここで私がする必要があるのは次のようなものだと思います。
myTreeMap.subMap(search.concat(X1)、true、search.concat(X2)、true);
ここで、X1とX2は可能な限り最高の文字と最低の文字です。
より良いアプローチはありますか?そうでない場合、X1とX2は何ですか?
前もって感謝します。
うーん。連結されていないが、代わりに「インクリメント」されているmyTreeMap.subMap(search, true, search2, false)
場所で実行する必要があると思います。search2
結局のところ、もしそれX2
が単なるキャラクターだったとしたら、あなたの実装は見逃してしまうでしょうsearch.concat(X2).concat(X2)
。
問題は、実行しようとしている部分的なキー検索です。
myTreeMap.subMap(search.concat(X1), true, search.concat(X2), true);
キーと値のペアがいくつかあると仮定しましょう。
fooBar->いくつかの値fooBage->いくつかの他の値barBear->価値のないアイデアbarTender->別の値
ここで、すべての「foo *」、この例ではfooBarとfooBageを検索します。キーは単一のトークンとして扱われ、この場合は文字列になります。キーを部分キーとして扱う方法はありません。「fooA」から「fooZ」が必要だと言っても、fooBarやfooBageは取得できません。
キークラス(これをFractionalKeyと呼びます)を作成し、equalsメソッドをオーバーライドすると、equalsを「一部の正規表現」または「全体または最初の部分のみ」などとして定義できます。これは、equalsがtrueを返す場合、ハッシュコードも等しくなければならないということです。これは、私が思うにそのルールを破ることになります。
これが唯一の選択肢だと思います。それ以外の場合は、キーのリストで目的のキーを検索します。
基本的に、2番目の境界として辞書式順序で次のプレフィックスが必要です。
public <T> Map<String, T> subMapWithKeysThatAreSuffixes(String prefix, NavigableMap<String, T> map) {
if ("".equals(prefix)) return map;
String lastKey = createLexicographicallyNextStringOfTheSameLenght(prefix);
return map.subMap(prefix, true, lastKey, false);
}
String createLexicographicallyNextStringOfTheSameLenght(String input) {
final int lastCharPosition = input.length()-1;
String inputWithoutLastChar = input.substring(0, lastCharPosition);
char lastChar = input.charAt(lastCharPosition) ;
char incrementedLastChar = (char) (lastChar + 1);
return inputWithoutLastChar+incrementedLastChar;
}
上記の回答に対する私の編集は、あまりにも独創的であるために拒否されたので、ここに投稿します。この回答はタイプミスを修正し、元の回答ではなかったintオーバーフローを処理します。
public <T> Map<String, T> subMapWithKeysThatAreSuffixes(String prefix, NavigableMap<String, T> map) {
if ("".equals(prefix)) return map;
String lastKey = createLexicographicallyNextStringOfTheSameLength(prefix);
return map.subMap(prefix, true, lastKey, false);
}
String createLexicographicallyNextStringOfTheSameLength(String input) {
final int lastCharPosition = input.length()-1;
String inputWithoutLastChar = input.substring(0, lastCharPosition);
char lastChar = input.charAt(lastCharPosition);
char incrementedLastChar = (char) (lastChar + 1);
// Handle int/char overflow. This wasn't done above.
if (incrementedLastChar == ((char) 0)) return input+incrementedLastChar;
return inputWithoutLastChar+incrementedLastChar;
}