不区分大小写的映射键 Java
CaseInsensitive Map Key Java
我有一个 Map<String, Object>
,我需要其中的字符串键不区分大小写
目前我正在将我的 String
对象包装在包装器中 class 我调用了 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)
和 return 的值,而不必执行 Map#get(CaseInsensitiveString.wrap(String))
。然而,在我的测试中,每当我尝试这样做时,我的 HashMap
都会 returned null 但是如果我在调用 get()
之前包装字符串它确实有效
是否可以让我的 HashMap
接受 get 方法的字符串和 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")));
和returns:
null
value
这符合预期:
看到这个:
Map<CaseInsensitiveString, String> test = new HashMap<>();
此行告诉 MAP 仅接受 CaseInsensitiveString 对象,当您将另一个对象传递给地图时,它会将其视为未知键和 returns null。
您可以通过将其更改为:
来获得所需的行为
Map<Object, String> test = new HashMap<>();
你可以这样做:
Map<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
见this question。
但是,请注意使用 TreeMap
而不是 HashMap
的性能影响,正如 Boris 在评论中提到的那样。
我有一个 Map<String, Object>
,我需要其中的字符串键不区分大小写
目前我正在将我的 String
对象包装在包装器中 class 我调用了 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)
和 return 的值,而不必执行 Map#get(CaseInsensitiveString.wrap(String))
。然而,在我的测试中,每当我尝试这样做时,我的 HashMap
都会 returned null 但是如果我在调用 get()
是否可以让我的 HashMap
接受 get 方法的字符串和 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")));
和returns:
null
value
这符合预期:
看到这个:
Map<CaseInsensitiveString, String> test = new HashMap<>();
此行告诉 MAP 仅接受 CaseInsensitiveString 对象,当您将另一个对象传递给地图时,它会将其视为未知键和 returns null。
您可以通过将其更改为:
来获得所需的行为Map<Object, String> test = new HashMap<>();
你可以这样做:
Map<String, Object> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
见this question。
但是,请注意使用 TreeMap
而不是 HashMap
的性能影响,正如 Boris 在评论中提到的那样。