2016-08-18 1 views
1

は、私は現在、私は私が呼ばれてきたラッパークラスCaseInsensitiveString次のようになりますそのためのコードで私のStringオブジェクトをラップしています CASEINSENSITIVE地図キーのJava

大文字と小文字を区別する文字列のキーを必要とする Map<String, Object>を持っています:

/** 
    * A string wrapper that makes .equals a caseInsensitive match 
    * <p> 
    *  a collection that wraps a String mapping in CaseInsensitiveStrings will still accept a String but will now 
    *  return a caseInsensitive match rather than a caseSensitive one 
    * </p> 
    */ 
public class CaseInsensitiveString { 
    String str; 

    private CaseInsensitiveString(String str) { 
     this.str = str; 
    } 

    public static CaseInsensitiveString wrap(String str) { 
     return new CaseInsensitiveString(str); 
    } 


    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null) return false; 

     if(o.getClass() == getClass()) { //is another CaseInsensitiveString 
      CaseInsensitiveString that = (CaseInsensitiveString) o; 
      return (str != null) ? str.equalsIgnoreCase(that.str) : that.str == null; 
     } else if (o.getClass() == String.class){ //is just a regular String 
      String that = (String) o; 
      return str.equalsIgnoreCase(that); 
     } else { 
     return false; 
     } 

    } 

    @Override 
    public int hashCode() { 
     return (str != null) ? str.toUpperCase().hashCode() : 0; 
    } 

    @Override 
    public String toString() { 
     return str; 
    } 
} 

私はMap<CaseInsensitiveString, Object>はまだMap#get(String)を受け入れ、Map#get(CaseInsensitiveString.wrap(String))を行うことなく、値を返すために得ることができるように期待していました。しかし、私のテストでは、私はこれを行うにしようとした時はいつでも私のHashMapはnullを返しましたが、私は私のHashMapが取得するために文字列とCaseInsensitiveString両方のパラメータを受け入れることができるようにget()

ことが可能ですを呼び出す前に、文字列をラップする場合には機能しませんメソッドと作業を行う場合は、Stringがラップされているかどうかにかかわらず、非機密ファッションで作業してください。もしそうなら、何が間違っていますか?

参考のために私のテストコードは次のようになります。

Map<CaseInsensitiveString, String> test = new HashMap<>(); 
    test.put(CaseInsensitiveString.wrap("TesT"), "value"); 
    System.out.println(test.get("test")); 
    System.out.println(test.get(CaseInsensitiveString.wrap("test"))); 

とリターン:予想通り

null 
value 
+3

主に速度の検討事項に応じて、['String.CASE_INSENSITIVE_ORDER']で' TreeMap'を使用できます(https://docs.oracle.com/javase/7/docs/api/java/lang /String.html#CASE_INSENSITIVE_ORDER)。 –

+1

自分のマップを拡張して、パットしたり取得したりするときにストリングを大文字/小文字に変換するだけでは、このトリックはできません。 –

+2

あなたは、すべてのキーを小文字(または大文字)に格納することができます。クエリの前には、クエリ文字列を小文字に変換します。 –

答えて

2

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

this questionを参照してください。

ただし、HashMapの代わりにTreeMapを使用した場合のパフォーマンス上の影響については、Boris氏のコメントに記載されています。

+0

これが重複していると思うなら、それに近い理由があります。そのように閉じるには、十分な評判があれば投票してください(または投票してください)。 –

+0

@SotiriosDelimanolis質問にフラグを立てる権限があることに気付かなかった、ありがとう! – mapeters

+0

これは完璧です!リンクのおかげで、私は前にそれを見つけることはなかった申し訳ありません:) – CrypticCabub

0

これは、次のとおりです。

Map<CaseInsensitiveString, String> test = new HashMap<>(); 

この:

はこれを参照してください。行はMAPにacを伝えますCaseInsensitiveStringオブジェクトのみを指定します。マップに別のオブジェクトを渡すと、不明なキーとして処理され、nullが返されます。

あなたはこれを変更することで、あなたに必要な動作を得ることができます:あなたはこのようにそれを行うことができます

Map<Object, String> test = new HashMap<>();