2016-08-18 11 views
1

我有一個Map<String, Object>在我需要的字符串鍵是不區分大小寫CASEINSENSITIVE圖例的Java

目前我在包裹包裝類我String對象,我叫CaseInsensitiveString對於其代碼如下所示:

/** 
    * 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每當我試圖做到這一點,但如果我呼籲get()

是否有可能之前包住的字符串,讓我HashMap接受字符串和CaseInsensitiveString參數來得到它確實工作方法和工作在不區分大小寫的情況下,無論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''(https://docs.oracle.com/javase/7/docs/api/java/lang)使用'TreeMap' /String.html#CASE_INSENSITIVE_ORDER)。 –

+1

簡單地擴展你自己的地圖,並把字符串轉換成大寫/小寫時,投入和獲取沒有伎倆? –

+2

您可以將所有密鑰存儲爲小寫(或高位)..並在查詢之前將查詢字符串轉換爲小寫。 –

回答

2

你可以這樣說:

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

this question

但是,請注意使用TreeMap而不是HashMap的性能影響,如Boris在評論中所述。

+0

如果你認爲這是重複的,那有很多理由。請標記(或者一旦你有足夠的聲望,就可以投票)以此結束。 –

+0

@SotiriosDelimanolis我沒有意識到我有權提出問題,謝謝! – mapeters

+0

這很完美!並感謝您的鏈接,對不起,我以前沒有找到它:) – CrypticCabub

0

這是預期:

看到這個:

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

這線將MAP告知ac只接受CaseInsensitiveString對象,當你將另一個對象傳遞給地圖時,它將視爲未知鍵並返回null。

您可以通過這個改變,讓您的要求的行爲:

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