繁体   English   中英

Java HashMap containsKey函数

[英]Java HashMap containsKey function

有人请告诉我HashMa p的函数containsKey()在内部如何工作。 是否使用equalshashcode函数来匹配键。 我正在为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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM