我想实现一个不区分大小写的哈希映射.这个问题本身并不新鲜,但我想增加额外的功能,不知道要采取什么样的方向.我希望客户能够做到这样的事情:
boolean preserve_case = true;
Map<String, MyClass> maplet = new CaseInsensitiveHashMap<MyClass>(preserve_case); // If the client enters true at construction, then the put, get, and remove methods should still be case insensitive, but the entry and key sets should preserve the case that the client used when calling put.
maplet.put("FoO", my_class);
MyClass bar = maplet.get("foo"); // Should return a reference to my_class
Set<Entry<String, MyClass>> case_sensitive_set = maplet.entrySet(); // Since the client input true to preserve order, this entry set should be ["FoO"=my_class.toString()]
Run Code Online (Sandbox Code Playgroud)
我能很好地处理这个问题; 我只是保持HashMap在后端.当客户端放入任何内容时,我会在将密钥添加到地图之前将其大写.
我只是很难写这些keySet()和entrySet()方法.我希望返回的条目集和键集由地图支持,这是Java映射的标准.
但是,我能想到处理这个问题的唯一方法是创建第二个支持数据结构,类似于a preserved_case_map,其中包含input.toUpperCase()=>输入作为键值对.当客户端调用entrySet()(或keySet())时,我可以通过循环遍历构造返回的条目集preserved_case_map.这里的问题是,如果我对其进行更改,则不会修改返回的条目集HashMap,除非我误解了某些内容......
让我知道这是否有意义,或者我是否正在卷入一个简单的情况.
And*_*ejs 26
您可以使用具有不区分大小写的比较器的TreeMap.TreeMap将使用比较器以不区分大小写的方式比较键:
Map<String, Integer> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
map.put("Foo", 1);
map.put("fOo", 2);
System.out.println(map.get("foo")); // prints 2
System.out.println(map.keySet()); // prints [Foo]
Run Code Online (Sandbox Code Playgroud)
要简化包装地图,您可以使用Googles Guava库中的ForwardingMap,但这是可选的.
在从支持映射中输入/获取内容之前,将String键包装在覆盖hashCode()/ equals()的类中,并使用包装器作为映射中的键.就像是:
class KeyWrapper {
int hashCode() {
return actualStringKey.toUpperCase().hashCode()
}
boolean equals(Object o) {...} // compare case-insensitive
}
Run Code Online (Sandbox Code Playgroud)
如果覆盖keySet(),则可以创建一个新集合并使用actualStringKeys填充它.
| 归档时间: |
|
| 查看次数: |
5725 次 |
| 最近记录: |