Java HashMap包含Key函数

时间:2014-07-17 06:27:34

标签: java hashmap

有人请告诉我containsKey() p的函数HashMa,它是如何在内部工作的。它是否使用equalshashcode函数来匹配密钥。我使用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"));
}

5 个答案:

答案 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有点生疏,但希望你会明白这一点。