【发布时间】:2010-09-17 18:34:34
【问题描述】:
有没有一个好方法可以让Map<String, ?> get 和 put 忽略大小写?
【问题讨论】:
标签: java map case-insensitive
有没有一个好方法可以让Map<String, ?> get 和 put 忽略大小写?
【问题讨论】:
标签: java map case-insensitive
TreeMap 扩展了 Map 并支持自定义比较器。
String 提供了一个默认的不区分大小写的比较器。
所以:
final Map<String, ...> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
比较器不考虑语言环境。在其 JavaDoc 中了解更多信息。
【讨论】:
您可以使用 Apache 的 Commons Collections 中的 CaseInsensitiveMap。
【讨论】:
Map<String, ?>。
是否可以实现自己的 Map 覆盖 put/get 方法?
public class CaseInsensitiveMap extends HashMap<String, String> {
...
put(String key, String value) {
super.put(key.toLowerCase(), value);
}
get(String key) {
super.get(key.toLowercase());
}
}
这种方法不会强制您更改“键”类型,而是更改您的 Map 实现。
【讨论】:
您需要一个用于 String 键的包装类,该类具有不区分大小写的 equals() 和 hashCode() 实现。使用它而不是 Map 的键的字符串。
请参阅http://www.java.happycodings.com/Java_Util_Package/code3.html 的示例实现,我在 2 分钟的谷歌搜索中找到了它。对我来说看起来很明智,虽然我从未使用过它。
【讨论】:
想到的三个明显的解决方案:
在使用字符串作为键之前对大小写进行规范化(非土耳其语区域设置的工作方式与世界其他地方不同)。
使用设计为用作键的特殊对象类型。这是处理复合键的常用习语。
将 TreeMap 与不区分大小写的 Comparator 一起使用(可能是 PRIMARY 或 SECONDARY 强度 java.text.Collator)。不幸的是,Java 库没有与 hashCode/equals 等效的 Comparator。
【讨论】:
您可以使用我的 Apache 许可 CaseInsensitiveMap 讨论 here。与 Apache Commons 版本不同,它保留了键的大小写。它比 TreeMap 更严格地实现了 map 契约(并且具有更好的并发语义)(详见博客 cmets)。
【讨论】:
Trove4j 可以为 HashMap 使用自定义散列。然而,鉴于无法缓存哈希码,这可能会对性能产生影响(尽管 Trove4j 可能已经找到了解决这个问题的方法?)。包装器对象(如 John M 所述)没有这种缓存缺陷。另请参阅我关于 TreeMap 的其他答案。
【讨论】:
在下面的链接中检查接受的答案。 How to check for key in a Map irrespective of the case?
底线是“最简单的解决方案是在插入/检查之前将所有输入简单地转换为大写(或小写)。您甚至可以编写自己的地图包装器来确保一致性。”
【讨论】: