Map<String, ?>
ケースを無視してgetとputを行う良い方法はありますか?
8 に答える
TreeMap は Map を拡張し、カスタム コンパレータをサポートします。
String は、大文字と小文字を区別しないデフォルトのコンパレータを提供します。
そう:
final Map<String, ...> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
コンパレーターはロケールを考慮しません。詳細については、その JavaDoc を参照してください。
Apache の Commons Collections からCaseInsensitiveMapを使用できます。
put/get メソッドをオーバーライドする独自の Map を実装することは可能でしょうか?
public class CaseInsensitiveMap extends HashMap<String, String> {
...
put(String key, String value) {
super.put(key.toLowerCase(), value);
}
get(String key) {
super.get(key.toLowercase());
}
}
このアプローチでは、「キー」タイプを変更する必要はありませんが、Map 実装を変更する必要があります。
大文字と小文字を区別しない equals() および hashCode() 実装を備えた String キーのラッパー クラスが必要です。マップのキーの文字列の代わりにそれを使用します。
http://www.java.happycodings.com/Java_Util_Package/code3.htmlで実装例を参照してください 。2 分間のグーグル検索で見つかりました。私はそれを使用したことはありませんが、私には賢明に見えます。
ここで説明したApache ライセンスの CaseInsensitiveMapを使用できます。Apache Commons バージョンとは異なり、キーの大文字と小文字が保持されます。TreeMap より厳密にマップ コントラクトを実装します (さらに、並行セマンティクスが優れています) (詳細については、ブログのコメントを参照してください)。
頭に浮かぶ3つの明白な解決策:
文字列をキーとして使用する前に、大文字と小文字を正規化します (トルコ語のロケールは、他の地域とは異なります)。
キーとして使用するように設計された特別なオブジェクト タイプを使用します。これは、複合キーを扱うための一般的なイディオムです。
大文字と小文字を区別しない Comparator (おそらく PRIMARY または SECONDARY 強度の java.text.Collator) で TreeMap を使用します。残念ながら、Java ライブラリには、hashCode/equals に相当する Comparator がありません。
以下のリンクで受け入れられた回答を確認してください。 大文字と小文字に関係なくマップでキーを確認する方法は?
要するに、「最も簡単な解決策は、挿入/チェックする前にすべての入力を大文字 (または小文字) に変換することです。一貫性を確保するために、これを行う独自の Map ラッパーを作成することもできます。」
Trove4jは、HashMap にカスタム ハッシュを使用できます。ただし、ハッシュコードをキャッシュできない場合、これはパフォーマンスに影響を与える可能性があります (ただし、Trove4j はこれを回避する方法を見つけた可能性があります)。ラッパー オブジェクト (John M によって説明されている) には、このキャッシングの欠陥はありません。TreeMap に関する他の回答も参照してください。