我想知道HashMap中是否存在特定的键,所以我使用的是containsKey(key)方法.但它区分大小写,即如果有一个带有Name的键并且我正在搜索名称,则它不会返回true.那么有什么方法我可以知道没有打扰钥匙的情况?
谢谢
And*_*yle 31
不是传统的地图.
"abc"是来自"ABC"的不同字符串,它们的哈希码是不同的,并且它们的equals()方法将相对于彼此返回false.
最简单的解决方案是在插入/检查之前简单地将所有输入转换为大写(或小写).您甚至可以编写自己的Map包装器,以确保一致性.
如果你想保持所提供的键的大小写,但是通过不区分大小写的比较,你可以考虑使用TreeMap并提供你自己的比较器,它将比较不区分大小写.然而,苦思冥想才去下来,你这条路线将结束与一些不可调和的矛盾-如果有人呼叫map.put("abc", 1),然后map.put("ABC", 2),什么情况下是存储在地图的关键?你能说得有意义吗?如果有人用标准包装您的地图,HashMap您是否会失去功能?或者,如果有人碰巧正在迭代你的密钥集,并且通过使用equals()你自己的快速"包含"检查会得到不一致的结果?还会有很多其他类似的案例. 请注意,您通过执行此操作违反了Map的约定(因为键的相等性是根据键上的equals()方法定义的)所以它在任何意义上都是不可行的.
维护严格的大写映射更容易使用和维护,并且具有实际上是合法的Map实现的优点.
Boz*_*zho 13
您可以使用TreeMap自定义,不区分大小写Comparator(使用String.compareToIgnoreCase())
例如:
Map<String, Something> map =
new TreeMap<String, Something>(CaseInsensitiveComparator.INSTANCE);
class CaseInsensitiveComparator implements Comparator<String> {
public static final CaseInsensitiveComparator INSTANCE =
new CaseInsensitiveComparator();
public int compare(String first, String second) {
// some null checks
return first.compareToIgnoreCase(second);
}
}
Run Code Online (Sandbox Code Playgroud)
更新:似乎String已将此定义Comparator为常量.
Bal*_*usC 13
使用TreeMap构造的String#CASE_INSENSITIVE_ORDER.
Map<String, String> map = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
map.put("FOO", "FOO");
System.out.println(map.get("foo")); // FOO
System.out.println(map.get("Foo")); // FOO
System.out.println(map.get("FOO")); // FOO
Run Code Online (Sandbox Code Playgroud)
要保留Map不变量,您可以自己创建密钥.实施合理hashCode/ equals你很高兴:
final class CaseInsensitive {
private final String s;
private final Local lc;
public CaseInsensitive (String s, Locale lc) {
if (lc == null) throw new NullPointerException();
this.s = s;
this.lc = lc;
}
private s(){ return s == null ? null : s.toUpperCase(lc); }
@Override
public int hashCode(){
String u = s();
return (u == null) ? 0 : u.hashCode();
}
@Override
public boolean equals(Object o){
if (!getClass().isInstance(o)) return false;
String ts = s(), os = ((CaseInsensitive)other).s();
if (ts == null) return os == null;
return ts.equals(os);
}
}
// Usage:
Map<CaseInsensitive, Integer> map = ...;
map.put(new CaseInsensitive("hax", Locale.ROOT), 1337);
assert map.get(new CaseInsensitive("HAX", Locale.ROOT) == 1337;
Run Code Online (Sandbox Code Playgroud)
注意:并非全世界的每个人都同意什么是大写的 - 一个着名的例子是土耳其语中的"i"的大写版本是"İ"而不是"I".
Map使用equals和hashCode来测试密钥相等性,并且您不能为String. 你可以做的是定义包含一个字符串值,你自己的Key类,但工具equals并hashCode在不区分大小写的方式。
| 归档时间: |
|
| 查看次数: |
44686 次 |
| 最近记录: |