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

如何在Java中创建自己的HashMap?,java,algorithm,data-structures,hashmap,Java,Algorithm,Data Structures,Hashmap,我知道散列算法,知道如何将“key”转换成一个等价的整数(使用一些数学上的随机表达式),然后将其压缩并存储到bucket中 但有人能给我指出一个应该用作基线的实现或至少是数据结构吗 我在web上的任何地方都没有找到它。创建一个实现java.util.Map接口的类,并填写给定的方法只需使用eclipse和最新的JDK即可。Java核心包的源代码随JDK一起提供。打开HashMap类,就可以开始了。一些方法实现可能来自AbstractMap、AbstractCollection等。这是因为适当的O

我知道散列算法,知道如何将“key”转换成一个等价的整数(使用一些数学上的随机表达式),然后将其压缩并存储到bucket中

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


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

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

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

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

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

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


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

创建自己的HashMap

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

2。put()方法将新条目放入hashmap。 使用哈希(哈希代码%SIZE)标识存储桶

a如果该存储桶中不存在任何元素:将其作为新条目放置

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

3。get()方法:返回hashmap中的元素
A.通过计算键的散列(hashcode%SIZE)来识别元素bucket,并使用equals方法返回元素。

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

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;
    }
}
类HashMapCustom{
私有条目[]表;//条目数组。
private int capacity=4;//HashMap的初始容量
静态类条目{
K键;
V值;
进入下一步;
公共输入(K键、V值、下一个输入){
this.key=key;
这个值=值;
this.next=next;
}
}
@抑制警告(“未选中”)
公共HashMapCustom(){
表=新条目[容量];
}
/**
*方法允许您将键值对放入HashMapCustom中。
*如果映射已经包含键的映射,则替换旧值。
*注意:方法不允许您放置null键,尽管它允许null值。
*实现还允许您将自定义对象作为键。
*主要功能:实施为您提供了以下功能:-
*>提供如何覆盖equals方法的完整功能。
*>提供如何覆盖hashCode方法的完整功能。
*
*@param newKey
*@param数据
*/
公共作废put(K newKey,V data){
if(newKey==null)
return;//不允许存储null。
//计算密钥的散列。
int hash=hash(newKey);
//创建新条目。
Entry newEntry=新条目(newKey,data,null);
//若表位置不包含任何条目,那个么将条目存储在那个里。
if(表[hash]==null){
表[hash]=newEntry;
}否则{
前一项=空;
当前条目=表[哈希];
而(当前!=null){//我们已经到达了bucket的最后一个条目。
if(当前键等于(新键)){
if(previous==null){//必须在bucket的第一个上插入节点。
newEntry.next=current.next;
表[hash]=newEntry;
返回;
}否则{
newEntry.next=current.next;
previous.next=newEntry;
返回;
}
}
先前=当前;
当前=当前。下一步;
}
previous.next=newEntry;
}
}
/**
*方法返回与键对应的值。
*
*@param-key
*/
公共V get(K键){
int hash=散列(键);
if(表[hash]==null){
返回null;
}否则{
Entry temp=表[hash];
while(temp!=null){
如果(温度键等于(键))
返回温度值;
temp=temp.next;//返回键对应的值。
}
return null;//如果找不到键,则返回null。
}
}
/**
*方法从HashMapCustom中删除键值对。
*
*@param-key
*/
公共布尔删除(K deleteKey){
int hash=hash(deleteKey);
if(表[hash]==null){
返回false;
}否则{
前一项=空;