【问题标题】:How to Create Own HashMap in Java?如何在 Java 中创建自己的 HashMap?
【发布时间】:2010-03-07 17:40:09
【问题描述】:

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

但是有人可以指出一个实现或至少应该用作基线的数据结构吗?

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

【问题讨论】:

  • 真正的目的是什么? Java 已经具有几个基于哈希的映射,这些映射可以重复使用并且在大多数情况下具有足够的质量。重写一个要么是重新发明轮子,要么是试图解决一个非典型的用例。了解您所处的情况会有所帮助。
  • 互联网鲜为人知的角落:en.wikipedia.org/wiki/Hash_table
  • JDK 的源代码可用,顺便说一句。这是HashMap 的实现:docjar.com/html/api/java/util/HashMap.java.html
  • 目的是“学习”所有DS的实现。我可以玩转所有其他 DS,但哈希对我和大多数 Java 开发人员来说仍然是个谜。
  • 我个人觉得 TreeMap 的实现要比 HashMap 复杂得多。

标签: java algorithm data-structures hashmap


【解决方案1】:

只需使用 eclipse 并使用最新的 JDK。 Java 核心包的源代码随 JDK 一起提供。打开 HashMap 类,你就可以开始了。一些方法实现可能来自 AbstractMap、AbstractCollection 等。这是因为正确的 OO 设计。您可以在 Eclipse 中导航到所有 JDK 类。

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

【讨论】:

  • Java 包的源代码随 JDK 一起提供。我看不出使用 Eclipse 有什么用。
  • 这可能是最好的方法。现在只需提取源代码,也许将其重写为伪代码以了解它的作用,然后实现您自己的并进行任何必要的更改。
【解决方案2】:

创建自己的 HashMap

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

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

2。 put() 方法将新条目放入哈希图中。 使用哈希(hashcode%SIZE)识别桶

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

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

3. get() 方法: 返回哈希图中的元素 一个。通过计算key的hash(hashcode%SIZE)来识别元素桶,用equals方法返回元素。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

        【解决方案5】:

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

        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;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-06
          • 2018-02-17
          • 1970-01-01
          • 2019-10-28
          • 1970-01-01
          • 2012-03-01
          相关资源
          最近更新 更多