有人请告诉我containsKey()
p的函数HashMa
,它是如何在内部工作的。它是否使用equals
或hashcode
函数来匹配密钥。我使用string
密钥用于hashmap
,当我动态使用密钥时,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"));
}
答案 0 :(得分:2)
密钥是Employee对象,而不是字符串,containsKey中有一个字符串。该比较将返回false,因为string" emp5"不等于对象Employee。
以下是containsKey doc:
的引用如果此映射包含指定键的映射,则返回true。更正式地说,当且仅当此映射包含键k的映射时才返回true(key == null?k == null:key.equals(k))
因为在你的情况下,key是一个字符串,'等于'将返回' true'只有当k是一个字符串并且其内容与key的内容相同时。
答案 1 :(得分:1)
您的代码有很多错误,这是无效的hm.put("new Employee("emp5")","emp4");
还使用带集合的通用类型
HashMap<String,employee> hm = new HashMap<String,employee>();
并将您命名为Employee
而非employee
,以类名开头。您也在调用new Employee
,而您的类名是employee
。
根据hashMap的source。它会在键上调用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"));
}
}
答案 2 :(得分:0)
更正代码:
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
。
您正在针对String键保存Employee对象。所以你需要检查有效密钥。在您的情况下,在向hashmap添加元素时,emp5
不用作键。
对于你的第二个问题: 它首先在内部检查密钥的哈希码。如果哈希码相同,它将检查equals方法。
答案 3 :(得分:0)
假设
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.
答案 4 :(得分:0)
在内部,可以使用链接列表数组实现哈希映射。
密钥被传递给一个例程(哈希),它返回一个数字。然后将数字除以数组的大小,得到余数。剩余部分是您随后前往的链接列表,以查看是否有任何节点与密钥完全匹配。
优点是,如果你有一个适当平衡的哈希函数,并且(比方说)一个包含32个项目的数组,你可以快速放弃在常量中搜索31/32(或+ 90%)的可能值时间运作。
存在其他实施手段;但是,它们在计算上是相似的。
Strings的(非常糟糕的)哈希算法的一个例子可能是简单地将所有ASCII字符值相加。非常好的哈希算法倾向于根据预期输入返回均匀分布的数字,其中增量输入不会逐渐填充相邻的桶。
因此,要查明哈希映射是否包含密钥,请在密钥上获取哈希函数的结果,然后向下走正确的链表,检查密钥存在的每个条目。
在C中,链表中的“节点”。
struct Node {
char* key;
char* value;
struct Node* next;
};
在C中,“hashmap”
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有点生疏,但希望你会明白这一点。