如何在Java中创建自己的HashMap?

时间:2010-03-07 17:40:09

标签: java algorithm data-structures hashmap

我知道哈希算法和hashCode()将“密钥”转换为等效整数(使用一些数学上的随机表达式),然后将其压缩并存储到存储桶中。

但有人能指出我应该用作基线的实现或至少数据结构吗?

我没有在网络上的任何地方找到它。

5 个答案:

答案 0 :(得分:3)

只需使用eclipse并使用最新的JDK。 Java核心包的源代码附带JDK。打开HashMap类,你很高兴。一些方法实现可能来自AbstractMap,AbstractCollection等。这是因为适当的OO设计。您可以在日食中导航到JDK的所有类。

更新:为什么选择Eclipe(或IDE)而不是只打开zip文件? IDE可用于在类之间来回移动,通常适用于“读取”代码。请注意,并非所有方法实现都在一个文件中,如HashMap.java,因此简单的文本编辑器(如notepad ++或textpad)可能还不够。像eclipse / IDEA这样完整的IDE可以让它变得更容易。至少它对我有用:)

答案 1 :(得分:2)

创建一个实现java.util.Map接口的类并填写给定的方法

答案 2 :(得分:1)

如果您想要快速且内存有效的实现,那么您将需要使用数组来支持您的地图。使用要索引到数组中的散列算法,并将对象存储在数组的该插槽中。

您需要注意许多小细节。何时调整数组大小,如何检测和解决哈希冲突等

我建议你的类实现java.util.Map,因为它可以让你很好地了解哪些方法是必要和有用的。

答案 3 :(得分:1)

创建自己的HashMap

http://javaexplorer03.blogspot.com/2015/10/create-own-hashmap.html

<强> 1。数据结构需要存储存储键值对。 创建一个Entry类来存储HashMap条目。 变量:键,值和下一个 next变量用于避免使用链接(链表)的hashmap冲突。

<强> 2。 put()方法将新条目放入hashmap中。 使用hash(hashcode%SIZE)

标识存储桶

一个。 如果该存储区中不存在任何元素:将其设为新条目

如果元素已存在: 如果元素是重复的,则替换旧的,否则找到链中的最后一个元素,并将新条目添加到最后一个元素的下一个指针。

第3。 get()方法:返回hashmap中的元素 一个。通过计算键的哈希值(哈希码%SIZE)来识别元素桶,并使用equals方法返回元素。

答案 4 :(得分:0)

尽管这是一个非常古老的问题,但我认为我应该为初学者提供一个易于理解的答案。

HashMap 简单解决方案的自定义实现:

   class HashMapCustom<K, V> {

    private Entry<K, V>[] table;   //Array of Entry.
    private int capacity = 4;  //Initial capacity of HashMap

    static class Entry<K, V> {
        K key;
        V value;
        Entry<K, V> next;

        public Entry(K key, V value, Entry<K, V> next) {
            this.key = key;
            this.value = value;
            this.next = next;
        }
    }


    @SuppressWarnings("unchecked")
    public HashMapCustom() {
        table = new Entry[capacity];
    }


    /**
     * Method allows you put key-value pair in HashMapCustom.
     * If the map already contains a mapping for the key, the old value is replaced.
     * Note: method does not allows you to put null key though it allows null values.
     * Implementation allows you to put custom objects as a key as well.
     * Key Features: implementation provides you with following features:-
     * >provide complete functionality how to override equals method.
     * >provide complete functionality how to override hashCode method.
     *
     * @param newKey
     * @param data
     */
    public void put(K newKey, V data) {
        if (newKey == null)
            return;    //does not allow to store null.

        //calculate hash of key.
        int hash = hash(newKey);
        //create new entry.
        Entry<K, V> newEntry = new Entry<K, V>(newKey, data, null);

        //if table location does not contain any entry, store entry there.
        if (table[hash] == null) {
            table[hash] = newEntry;
        } else {
            Entry<K, V> previous = null;
            Entry<K, V> current = table[hash];

            while (current != null) { //we have reached last entry of bucket.
                if (current.key.equals(newKey)) {
                    if (previous == null) {  //node has to be insert on first of bucket.
                        newEntry.next = current.next;
                        table[hash] = newEntry;
                        return;
                    } else {
                        newEntry.next = current.next;
                        previous.next = newEntry;
                        return;
                    }
                }
                previous = current;
                current = current.next;
            }
            previous.next = newEntry;
        }
    }

    /**
     * Method returns value corresponding to key.
     *
     * @param key
     */
    public V get(K key) {
        int hash = hash(key);
        if (table[hash] == null) {
            return null;
        } else {
            Entry<K, V> temp = table[hash];
            while (temp != null) {
                if (temp.key.equals(key))
                    return temp.value;
                temp = temp.next; //return value corresponding to key.
            }
            return null;   //returns null if key is not found.
        }
    }


    /**
     * Method removes key-value pair from HashMapCustom.
     *
     * @param key
     */
    public boolean remove(K deleteKey) {

        int hash = hash(deleteKey);

        if (table[hash] == null) {
            return false;
        } else {
            Entry<K, V> previous = null;
            Entry<K, V> current = table[hash];

            while (current != null) { //we have reached last entry node of bucket.
                if (current.key.equals(deleteKey)) {
                    if (previous == null) {  //delete first entry node.
                        table[hash] = table[hash].next;
                        return true;
                    } else {
                        previous.next = current.next;
                        return true;
                    }
                }
                previous = current;
                current = current.next;
            }
            return false;
        }

    }


    /**
     * Method displays all key-value pairs present in HashMapCustom.,
     * insertion order is not guaranteed, for maintaining insertion order
     * refer LinkedHashMapCustom.
     *
     * @param key
     */
    public void display() {

        for (int i = 0; i < capacity; i++) {
            if (table[i] != null) {
                Entry<K, V> entry = table[i];
                while (entry != null) {
                    System.out.print("{" + entry.key + "=" + entry.value + "}" + " ");
                    entry = entry.next;
                }
            }
        }

    }

    /**
     * Method implements hashing functionality, which helps in finding the appropriate
     * bucket location to store our data.
     * This is very important method, as performance of HashMapCustom is very much
     * dependent on  this method's implementation.
     *
     * @param key
     */
    private int hash(K key) {
        return Math.abs(key.hashCode()) % capacity;
    }
}