web-dev-qa-db-ja.com

大文字と小文字を区別せずにMap <String、?>を取得および配置する良い方法はありますか?

Map<String, ?>を取得して大文字と小文字を区別しないようにする良い方法はありますか?

61
Joshua

TreeMapはMapを拡張し、カスタムコンパレータをサポートします。

文字列は、デフォルトの大文字と小文字を区別しないコンパレータを提供します。

そう:

final Map<String, ...> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);

コンパレーターはロケールを考慮しません。詳細については、JavaDocを参照してください。

62
volley

ApacheのCommons Collectionの CaseInsensitiveMap を使用できます。

42
Eric Weilnau

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());
    }
}

このアプローチでは、「キー」タイプを変更する必要はありませんが、マップの実装を変更する必要があります。

31
Guido

大文字と小文字を区別しないequals()およびhashCode()を実装したStringキーのラッパークラスが必要です。文字列の代わりにそれをマップのキーに使用します。

http://www.Java.happycodings.com/Java_Util_Package/code3.html で実装例を参照してください。2分間のグーグル検索で見つかりました。私はそれを使用したことがないが、私には賢明に見えます。

14
John M

私のApacheライセンス CaseInsensitiveMap 説明 ここ を使用できます。 Apache Commonsバージョンとは異なり、キーの大文字と小文字が保持されます。 TreeMapより厳密にマップコントラクトを実装します(さらに、同時セマンティクスが向上します)(詳細については、ブログのコメントを参照してください)。

3
Glyn Normington

思い浮かぶ3つの明白な解決策:

  • 文字列をキーとして使用する前に、ケースを正規化します(トルコ語のロケールは他の地域とは動作が異なります)。

  • キーとして使用するために設計された特別なオブジェクトタイプを使用します。これは、複合キーを処理するための一般的なイディオムです。

  • 大文字と小文字を区別しないComparator(おそらくPRIMARYまたはSECONDARY強度のJava.text.Collat​​or)でTreeMapを使用します。残念ながら、Javaライブラリには、hashCode/equalsに相当するコンパレータがありません。

Trove4j HashMapにカスタムハッシュを使用できます。ただし、ハッシュコードをキャッシュできないため、これはパフォーマンスに影響する可能性があります(ただし、Trove4jはこれを回避する方法を見つけた可能性があります)。ラッパーオブジェクト(John Mが説明)には、このキャッシングの欠陥はありません。 TreeMapに関する他の回答も参照してください。

0
volley

以下のリンクで承認された回答を確認してください。 ケースに関係なく、マップ内のキーを確認する方法

結論は、「最も簡単な解決策は、挿入/チェックの前にすべての入力を大文字(または小文字)に変換することです。一貫性を確保するためにこれを行う独自のマップラッパーを作成することもできます。」

0
Kunjan