【问题标题】:Java Hash Tables and Hash MapsJava 哈希表和哈希映射
【发布时间】:2018-10-13 20:51:54
【问题描述】:

已经使用 Java 一段时间了,但又遇到了另一个问题。 HashMap 或 HashTable。

已经了解了基础知识..哈希表是如何实现的..就像计算哈希值..在哈希值(或者可能是哈希值 % maxArray)索引处存储数据..线性探测和链接冲突。 现在更进一步,如果有人可以在下面提供帮助:

基本示例展示了将“Jhon”、“Lisa”、“Sam”等字符串存储在数组中,然后通过冲突并将数组转换为链接列表以存储名称,这一切都很好理解并且非常好。

  1. 但是哈希表存储键值对。那么它是如何实现的呢?
  2. 键、值对示例显示“电话目录”示例,但未显示它们如何存储在数组或链表中。它只是 Map.put(k,v) 和 Map.get(k)。链表存储“一个数据”和“指针”.. 那么我们如何在链表中存储键和值(图片可能有助于理解)
  3. 比 map.put("Rocket", 01111111111) 更实用的哈希表示例。

【问题讨论】:

  • 感谢您的链接!因此,如果我理解正确..我们传递的所有 Key、Value 对象都将传递给 Entry/Node 类对象,该对象作为单个元素存储在链表中。该对象的属性是我们的键、值,所有进一步的操作都在这些属性上执行。此外,如果我们实现哈希映射,那么是否必须重写 obj.equals() 函数,因为是开发人员决定 2 个对象如何相等?还是java默认检查对象的每个属性是否相等?谢谢!!
  • 是的,在 java 中 HashMap 使用 Entry 存储键和值的对象。开发人员必须重写 hashCode()equals() 才能将其自定义类的对象用作 HashMap 中的键。

标签: java hashmap hashtable associative-array


【解决方案1】:
  1. 但是哈希表存储键值对。那么它是如何实现的呢?

想象一下这样的数据结构:

Node<K, V>[] table;

public static class Node<K, V> {
    //voila! Key and Value stored here
    private K key;
    private V value;
    //make it a linked list
    private Node<K, V> next;

}
  1. 键、值对示例显示“电话目录”示例,但未显示它们如何存储在数组或链表中。它只是 Map.put(k,v) 和 Map.get(k)。链表存储“一个数据”和“指针”.. 那么我们如何在链表中存储键和值(图片可能有助于理解)

检查点 1。

  1. 比 map.put("Rocket", 01111111111) 更实用的哈希表示例。

给你:

public class PersonIdentifier {
    private final int id;
    private final String ssn;

    public PersonIdentifier(int id, String ssn) {
        this.id = id;
        this.ssn = ssn;
    }
    //getters, NO setters since fields are final...

    //now the relevant methods!
    @Override
    public int hashCode() {
        //available since Java 7...
        return Objects.hash(id, ssn);
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) return null;
        if (this == o) return true;
        if (!o.getClass().equals(this.getClass())) return false;
        Person another = (Person)o;
        return another.id == this.id && another.ssn.equals(this.ssn);
    }
}

//...

Map<PersonIdentifier, Person> peopleMap = new HashMap<>();
peopleMap.put(new PersonIdentifier(1, "123456789"), new Person(/* fill with values like firstName, lastName, etc... */));
peopleMap.put(new PersonIdentifier(2, "987654321"), new Person(/* fill with values like firstName, lastName, etc... */));
//and on...

【讨论】:

  • 非常感谢!!还刚刚注意到您的构造函数名称似乎有错字..但我明白了。所以我们的关键是 PersonIdentifer,有 2 个属性 id 和 ssn,如果我们要从地图中提取细节,那么我们需要 id 和 ssn 的精确组合。对吗?只保留 ssn 作为密钥不是更好吗,这样我们只需知道 ssn 就可以提取人员详细信息,而不必担心 id..如果我遗漏了什么,请告诉我?顺便说一句,演示实际用途的绝佳示例..这就是我想要的..谢谢!!
  • 抱歉,错字已修正。是的,我们需要 id 和 field 这两个组件的组合。我之所以这样设计它,是因为您说“哈希表比 map.put("Rocket", 01111111111) 更实用一点。”所以这是一个例子,只是一个例子,当有多个字段来识别你的数据时如何使用地图。您可以使用 Map&lt;String, Person&gt; peopleMap 并使用 SSN 作为唯一键来简化此示例。
猜你喜欢
  • 2016-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 1970-01-01
  • 2016-04-24
  • 1970-01-01
相关资源
最近更新 更多