我收到了HashMap
个数据:
Map<CharSequence, MyObject> dataMap = GET_FROM_SOME_WHERE
dataMap
中有一个键是CharSequence
类型,其值为“company.name”
但是以下代码会返回 false :
String field = "company.name";
dataMap.containsKey(field); //This return me false
我不知何故觉得这是因为我的字段变量是String
对象,而HashMap中的键是CharSequence
。这就是为什么它让我失意。
如果我的猜测是正确的,那么如何摆脱它呢?我需要上面的代码返回我的真实。我确信关键字“company.name”在该地图数据中是关键。
答案 0 :(得分:4)
Java API Spec对此主题有这样的说法:
'每个对象可以由不同的类实现,并且不能保证每个类都能够测试其实例与另一个类的实例是否相等。因此,将任意CharSequence实例用作集合中的元素或映射中的键是不合适的。
答案 1 :(得分:1)
为什么不放
CharSequence field = "company.name";
答案 2 :(得分:1)
您是否将StringBuffers放入HashMap?因为这不起作用,因为StringBuffer没有定义hashCode方法。它从java.lang.Object继承hashCode,它使用对象的标识作为哈希码。
另一方面,String从实际的字符串数据中计算哈希码。
编辑:StringBuffer也没有实现equals()方法,所以它根本不会像人们期望的那样工作。 (new StringBuffer(“1”))。equals(new StringBuffer(“1”)) - &gt;假的。
答案 3 :(得分:1)
为了实现这一点,地图中CharSequence
的实现必须识别String
以检查相等性,使用String
生成相同的哈希码,然后返回{{当将相等性与具有相同值的字符串进行比较时(即true
应该从两端起作用)。除非equals
的实施实际上是CharSequence
。
解决此问题的一种方法是将String
转换为Map<CharSequence,MyObject>
。迭代原始地图的入口集,并将数据放入使用Map<String,MyObject>
作为键的副本中,如下所示:
String
答案 4 :(得分:1)
有时使用Collection非常棘手。
Map.containsKey()的工作方式是通过调用“key”对象的.equals()方法来检查对象的相等性。所以,如果你通过 StringBuffer (也实现CharSequence)将东西放入地图中,但是试着询问地图中是否存在密钥,但是提供了 String 作为密钥,你真的在挑战Collections框架。 这可以通过以下示例显示:
Map<CharSequence, Integer> dataMap = new HashMap<CharSequence, Integer>();
StringBuffer sb = new StringBuffer();
sb.append("company.name");
CharSequence cs = sb;
dataMap.put(cs, 123);
String k = "company.name";
// Below prints a 'false'
System.out.println(dataMap.containsKey(k));
因此,我的建议是始终使用相同类型的对象作为集合中的键条目(不仅仅是Map)。在这种情况下,您也可以将地图定义为
Map<String, MyObject>
答案 5 :(得分:0)
可能的原因是地图中使用了equals()
方法。另一个是使用hashCode()
。如果map中的键不是String,它可以通过这些方法为您提供其他值。
如果你在某个地方得到地图并且无法控制它,那么迭代按键设置似乎是唯一的方法。否则我建议将地图更改为Map<String, MyObject>
public static void main(String[] args) {
Map<CharSequence, String> dataMap = new HashMap<>();
dataMap.put(new StringBuilder("company.name"), "AAA");
System.out.println(dataMap.containsKey("company.name"));
System.out.println(mapContainsKeyNamed("company.name", dataMap));
}
static boolean mapContainsKeyNamed(String key, Map<CharSequence, ?> map) {
for (CharSequence cs : map.keySet()) {
if (key.equals(cs.toString())) {
return true;
}
}
return false;
}
输出:
false
true