【发布时间】:2016-12-25 20:33:22
【问题描述】:
我有一个Map<String, Object>,其中我需要字符串键不区分大小写
目前我正在将我的 String 对象包装在一个名为 CaseInsensitiveString 的 Wrapper 类中,其代码如下所示:
/**
* 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 参数到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
【问题讨论】:
-
根据你想要的,主要是速度方面的考虑,你可以使用
TreeMap和String.CASE_INSENSITIVE_ORDER。 -
简单地扩展您自己的地图并在放置和获取时将字符串转换为大写/小写并不能解决问题?
-
您可以将所有键存储为小写(或大写)。在查询之前,将查询字符串转换为小写。
-
那些转换为大写/小写的解决方案在这里可能是可行的,但是我正在处理使用 CasePreservation 的外部 api 的接口,我希望尽可能保持这一点跨度>
标签: java string hashmap case-insensitive