首页 > 代码库 > 链地址法实现HashMap

链地址法实现HashMap

前注:本文介绍的HashMap并非Java类库的实现。而是根据哈希表知识的一个实现。

上文介绍了开放地址法实现HashTable,它的缺点是对hashCode映射为地址后如果出现重复地址,则会占用其他元素的位置。这样HashTable存储容量有限,而且不便于算法理解。本文介绍链地址法实现HashMap。

链地址法内部仍然有一个数组,但区别与开放地址法,该数组存储的是一个链表的引用。当根据hashCode计算出数组下表后,对元素的增删查改都是在该数组元素所指向的链表上完成的。这就解决了hashCode重复的问题。因为,当hashCode重复,多个元素对应同一个地址,但元素实际存储的位置在数组对应的链表上。所以相同hashCode的不同元素可以存储在同一位置。

下面是代码实现:

技术分享
package org.lyk.impl;

import java.util.ArrayList;
import org.lyk.interfaces.IMap;

public class HashMap<K,V> implements IMap<K, V>
{
    private class KeyValue
    {
        private K key;
        private V value;
        
        public KeyValue(K key, V value)
        {
            this.key = key;
            this.value =http://www.mamicode.com/ value;
        }
        
        
        public K getKey()
        {
            return key;
        }
        public void setKey(K key)
        {
            this.key = key;
        }
        public V getValue()
        {
            return value;
        }
        public void setValue(V value)
        {
            this.value =http://www.mamicode.com/ value;
        }
        
        
    }
    private int maxSize = 10;
//    private int currentAmmount = 0;
    private Object[] table;
    
    
    
    public HashMap()
    {
        this.table = new Object[this.maxSize];
        for(int i = 0; i < this.maxSize; i++)
        {
            this.table[i] = new java.util.ArrayList<KeyValue>();
        }
    }
    
    @Override
    public void add(K key, V value)
    {
        int index = this.getIndex(key);
        ((java.util.List<KeyValue>)this.table[index]).add(new KeyValue(key, value));
    }

    @Override
    public boolean remove(K key)
    {
        int index = this.getIndex(key);
        java.util.List<KeyValue> kvs = (java.util.List<KeyValue>)this.table[index];
        int listIndex = -1;
        for(KeyValue kv : kvs)
        {
            if(kv.key.equals(key))
            {
                listIndex = kvs.indexOf(kv);
            }
        }
        if(listIndex != -1)
        {
            kvs.remove(listIndex);
            return true;
        }
        return false;
    }

    @Override
    public V get(K key)
    { 
        KeyValue kv= this.find(key);
        if(kv != null)
            return kv.getValue();
        else
            return null;
    }

    @Override
    public boolean contains(K key)
    { 
        if(this.get(key) != null)
            return true;
        else
            return false;
    }

    @Override
    public void replace(K key, V value)
    {
        KeyValue kv = this.find(key);
        if(kv != null)
        {
            kv.setValue(value);
            
        }
    }
    
    private int getIndex(K key)
    {
        return Math.abs(key.hashCode())%this.maxSize;
    }
    
    private KeyValue find(K key)
    {
        int index = this.getIndex(key);
        java.util.List<KeyValue> kvs = (java.util.List<KeyValue>)this.table[index];
        int listIndex = -1;
        for(KeyValue kv : kvs)
        {
            if(kv.key.equals(key))
            {
                return kv;
            }
        }
        
        return null;
    }
}
HashMap
技术分享
package org.lyk.impl;

import java.math.BigInteger;

public class Info
{
    private String name;
    private String address;
    private Integer age; 
    
    
    public Info(String name, String address, Integer age)
    {
        super();
        this.name = name;
        this.address = address;
        this.age = age;
    }
    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((address == null) ? 0 : address.hashCode());
        result = prime * result + ((age == null) ? 0 : age.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    
//    @Override
//    public int hashCode()
//    {
//        final int prime = 27;
//        int result = 1;
//        result = prime*result + (this.name == null ? 0:this.name.hashCode());
//        result = prime*result + (this.address == null ? 0:this.address.hashCode());
//        result = prime*result + (this.age == null ? 0 : this.age.hashCode());
//        return result;
//    }
    
    
    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Info other = (Info) obj;
        if (address == null)
        {
            if (other.address != null)
                return false;
        } else if (!address.equals(other.address))
            return false;
        if (age == null)
        {
            if (other.age != null)
                return false;
        } else if (!age.equals(other.age))
            return false;
        if (name == null)
        {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }
    public String getAddress()
    {
        return address;
    }
    public void setAddress(String address)
    {
        this.address = address;
    }
    public Integer getAge()
    {
        return age;
    }
    public void setAge(Integer age)
    {
        this.age = age;
    }
    @Override
    public String toString()
    {
        return "Info [name=" + name + ", address=" + address + ", age=" + age
                + "]";
    }
    
    
    
    
}
Info
技术分享
package org.lyk.main;
 

import java.util.ArrayList;
import java.util.List;

import org.lyk.impl.HashMap;
import org.lyk.impl.Info;
 

 

public class Main
{
    public static void main(String[] args)
    {
        HashMap<String, Info> hm = new HashMap<String, Info>();
        for(int i = 0; i < 15; i++)
        {
            hm.add("sheldon" + i, new Info("sheldon" + i, "address" + i, i));
        } 
        
        String key = "sheldon12";
        Info sheldon12 = new Info("sheldon12", "洛杉矶", 99);
        System.out.println(hm.get(key));
        hm.replace(key, sheldon12);
        System.out.println(hm.get(key));
        hm.remove(key);
        System.out.println(hm.get(key));
        System.out.println("///~ main done");
    } 
     
}
Main测试

 

链地址法实现HashMap