鏈地址法實現HashMap


前注:本文介紹的HashMap並非Java類庫的實現。而是根據哈希表知識的一個實現。

上文介紹了開放地址法實現HashTable,它的缺點是對hashCode映射為地址后如果出現重復地址,則會占用其他元素的位置。這樣HashTable存儲容量有限,而且不便於算法理解。本文介紹鏈地址法實現HashMap。

鏈地址法內部仍然有一個數組,但區別與開放地址法,該數組存儲的是一個鏈表的引用。當根據hashCode計算出數組下表后,對元素的增刪查改都是在該數組元素所指向的鏈表上完成的。這就解決了hashCode重復的問題。因為,當hashCode重復,多個元素對應同一個地址,但元素實際存儲的位置在數組對應的鏈表上。所以相同hashCode的不同元素可以存儲在同一位置。

下面是代碼實現:

package org.lyk.interfaces;

public interface IMap<K,V>
{
    /**
     * 根據key值增加一個value,如果key重復,則新元素替換舊元素
     * @param key
     * @param value
     */
    public void put(K key, V value);
    /**
     * 根據key值移除value
     * @param key
     * @return
     */
    public boolean remove(K key);
    public V get(K key);
    public boolean contains(K key);
    public void replace(K key, V value);
    
}
IMap
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 = 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 = value;
        }
        
        
    }
    private int maxSize = 10; 
    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 put(K key, V value)
    {
        int index = this.getIndex(key);
        KeyValue  kv = this.find(key);
        if(kv == null)
        {
            ((java.util.List<KeyValue>)this.table[index]).add(new KeyValue(key, value));
        }
        else
        {
            kv.setValue(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]; 
        for(KeyValue kv : kvs)
        {
            if(kv.key.equals(key))
            {
                return kv;
            }
        }
        
        return null;
    }
}
HashMap

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM