64

有没有一个好方法可以Map<String, ?>忽略大小写?

4

8 回答 8

70

TreeMap 扩展了 Map 并支持自定义比较器。

String 提供了一个默认的不区分大小写的比较器。

所以:

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

比较器不考虑语言环境。在其 JavaDoc 中阅读有关它的更多信息。

于 2009-12-09T20:55:41.450 回答
42

您可以使用Apache 的 Commons Collections 中的CaseInsensitiveMap

于 2008-10-17T15:16:35.463 回答
32

是否可以实现自己的 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 实现。

于 2008-10-17T15:23:28.037 回答
14

您需要一个带有不区分大小写的 equals() 和 hashCode() 实现的 String 键的包装类。使用它而不是 Map 的键的字符串。

请参阅http://www.java.happycodings.com/Java_Util_Package/code3.html上的示例实现, 我在 2 分钟的谷歌搜索中找到了它。对我来说看起来很明智,虽然我从未使用过它。

于 2008-10-17T15:11:44.940 回答
3

想到的三个明显的解决方案:

  • 在使用字符串作为键之前对大小写进行规范化(不是土耳其语区域设置与世界其他地方的工作方式不同)。

  • 使用设计用作键的特殊对象类型。这是处理复合键的常用习语。

  • 将 TreeMap 与不区分大小写的 Comparator 一起使用(可能是 PRIMARY 或 SECONDARY 强度 java.text.Collat​​or)。不幸的是,Java 库没有与 hashCode/equals 等效的比较器。

于 2008-10-17T15:46:08.740 回答
3

您可以使用此处讨论的我的 Apache 许可CaseInsensitiveMap。与 Apache Commons 版本不同,它保留了键的大小写。它比 TreeMap 更严格地实现了 map 契约(加上具有更好的并发语义)(详见博客评论)。

于 2009-04-30T14:23:37.953 回答
0

Trove4j可以为 HashMap 使用自定义散列。然而,鉴于无法缓存哈希码,这可能会对性能产生影响(尽管 Trove4j 可能已经找到了解决这个问题的方法?)。包装器对象(如 John M 所述)没有这种缓存缺陷。另请参阅我关于 TreeMap 的其他答案。

于 2009-12-09T20:54:06.977 回答
0

在下面的链接中检查接受的答案。 无论情况如何,如何检查 Map 中的密钥?

底线是“最简单的解决方案是在插入/检查之前简单地将所有输入转换为大写(或小写)。您甚至可以编写自己的地图包装器来确保一致性。”

于 2013-03-29T07:43:53.210 回答