[英]Java HashMap containsKey function
有人请告诉我HashMa
p的函数containsKey()
在内部如何工作。 是否使用equals
或hashcode
函数来匹配键。 我正在为hashmap
使用string
键,当我动态使用键时, containskey
返回false
。 例如(只是示例代码,而不是我在应用程序中使用的原始代码)
class employee {
employee(String name) {
return name;
}
}
class test {
HashMap hm = new HashMap();
hm.put("key1",new Employee("emp1"));
hm.put("key2",new Employee("emp2"));
hm.put("key3","emp4");
hm.put("new Employee("emp5")","emp4");
System.out.println(hm.containsKey("emp5"));
}
键是一个Employee对象,而不是字符串,在containsKey中,您有一个字符串。 该比较将返回false,因为字符串“ emp5”不等于对象Employee。
这是一个来自containsKey doc的报价:
如果此映射包含指定键的映射,则返回true。 更正式地讲,当且仅当此映射包含键k的映射时返回true,这样(key == null?k == null:key.equals(k))
因为在您的情况下,键是一个字符串,所以仅当k也是一个字符串并且其内容与键的内容相同时,“等于”才会返回“真”。
您的代码有很多错误,这是无效的hm.put("new Employee("emp5")","emp4");
还要对集合使用通用类型
HashMap<String,employee> hm = new HashMap<String,employee>();
然后将您的班级名称命名为Employee
而不是employee
,并以大写字母开头。 另外,您正在呼叫new Employee
而您的类名是employee
。
根据hashMap的来源 。 它在内部调用键上的equals()
(在您的情况下,它equals
String
)
public boolean containsKey(Object key)
{
int idx = hash(key);
HashEntry<K, V> e = buckets[idx];
while (e != null)
{
if (equals(key, e.key))
return true;
e = e.next;
}
return false;
}
您的有效代码(假设您没有尝试实现不寻常的功能)应如下所示:-
class Employee {
String name;
Employee(String name) {
this.name = name;
}
}
class Test {
public void hello() {
HashMap<String,Employee> hm = new HashMap<String,Employee>();
hm.put("key1", new Employee("emp1"));
hm.put("key2", new Employee("emp2"));
hm.put("key3", new Employee("emp4"));
hm.put("key4", new Employee("emp5"));
System.out.println(hm.containsKey("key4"));
}
}
更正的代码:
HashMap hm= new HashMap();
hm.put("key1",new Employee("emp1"));
hm.put("key2",new Employee("emp2"));
hm.put("key3","emp4");
System.out.println(hm.containsKey("key1"));
这将返回true
。
您正在针对字符串键保存Employee对象。 因此,您需要检查有效密钥。 在您的情况下,在将元素添加到哈希图中时, emp5
不用作键。
对于您的第二个问题:它首先在内部检查密钥的哈希码。 如果哈希码相同,则将检查equals方法。
假设
employee(String name) {
return name;
}
不是constructor
,而是这段代码无法编译的某些方法。 当您返回String
却在方法中指定返回类型。
此外,此行hm.put("new Employee("emp5")","emp4");
您已将密钥指定为
new Employee("emp5")
并且您正在使用containsKey()中的键emp5
进行搜索,显然它将返回false,因为
containsKey() -Returns true if this map contains a mapping for the specified key.
在内部,哈希映射可以通过一系列链接列表来实现。
密钥被传递到例程(散列),该例程返回一个数字。 然后将数字除以数组的大小,得到余数。 剩下的就是您随后要查看的任何节点是否与键完全匹配的链表。
优点是,如果您具有适当平衡的哈希函数,并且(例如)由32个项目组成的数组,则可以在恒定时间操作中快速放弃对31/32(或+ 90%)可能值的搜索。
存在其他实施方式; 但是,它们在计算上相似。
字符串(非常糟糕)哈希算法的一个示例可能是简单地将所有ASCII字符值相加。 很好的哈希算法往往会根据预期的输入返回均匀分布的数字,其中增量输入不会增量填充相邻的存储桶。
因此,要查找哈希映射是否包含键,请获取键上哈希函数的结果,然后向下浏览正确的链接列表,检查每个条目是否存在键。
在C中,链表中的一个“节点”。
struct Node {
char* key;
char* value;
struct Node* next;
};
在C中,“哈希图”
struct HashMap {
int size;
struct Node* listRoots;
};
算法
int containsKey(HashMap* hashMap, char* key) {
int hash = hashFunc(key);
Node* head = hashMap->listRoots[hash % hashMap->size];
while (head != 0) {
if (strcmp(head->key, key)) {
return TRUE;
}
}
return FALSE;
}
请记住,我的C有点生锈,但是希望您会明白的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.