根据hashmap理解的底层实现原理,手撸hashMap代码。hashmap源码浅析

与javaAPI中的实现方式思想相通实现细节不同,不过更容易理解!

话不多说,直接上代码!代码中有关键部分的解释:

接口Entry<K,V>

public interface Entry<K,V> {
     K getKey();
     V getValue();
     V setValue(V value);
}

hashMap实现类,只要实现了put和get方法

/**
 * 根据hashmap底层实现,自己简单的手撸一个hashmap
 *
 * @author wolf
 * @create 2018-06-06    14:32
 */
public class wolfHashMap<K, V> {
    //default size of hashMap;桶的默认大小
     static int DEFAULTSIZE = 16;
    //hashMap's factor to resize 加载影子,当当前的hashmap存储的元素个数大于DEFAULTSIZE*FACTOR,就需要rehash和resize
     static double FACTOR = 0.75;
    //define length of elements in hashMap
    int size_eles = 0;
    //define arrays of story
    Node<K, V>[] node;

    //define the node of store in hashMap
    class Node<K, V> implements Entry<K, V> {
        private K key;

        private V value;
        Node<K, V> next;

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

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V value) {
            V result = this.value;
            this.value = value;
            return result;
        }
    }

    //构造函数
    public wolfHashMap() {
        this.node = new Node[DEFAULTSIZE];
    }

    public wolfHashMap(int size, double factor) {
        this.DEFAULTSIZE = size;
        this.FACTOR = factor;
        this.node = new Node[DEFAULTSIZE];
    }

    //put方法的实现
    public V put(K key, V value) {
        V result = null;
        //添加之前看是否需要扩容,扩容的时候需要resize和rehash
        if (size_eles >= DEFAULTSIZE * FACTOR)
            resize(size_eles);
        int index = hashCode(key);
        //在添加之前还要判断添加的key是否已经存在于hash表中
        Node temp = node[index];
        while (temp != null) {//在这里处理相同key情况。key相同时,将value替换成原来的value,并将旧的value返回
            if (temp.getKey() == key) {
                result = (V) temp.getValue();
                temp.value = value;
                return result;
            }
            temp = temp.next;
        }
        //能到这里来说明新添加的节点与原来存储的数据都不冲突
        node[index] = new Node<>(key, value, null);
        node[index].next = temp;
        size_eles++;
        return result;
    }

    //get方法
    public V get(K key) {
        int index = hashCode(key);
        Node cur = node[index];
        while (cur != null) {
            if (cur.getKey() == key)
                return (V) cur.getValue();
            cur = cur.next;
        }
        //找不到返回null
        return null;
    }

    //获取存储元素的个数
    public int size() {
        return size_eles;
    }


    //扩容方法,每次在现有的容量上扩大2倍
    private void resize(int size) {
        Node<K, V>[] newNode = new Node[DEFAULTSIZE * 2];
        DEFAULTSIZE = DEFAULTSIZE * 2;
        //将原来hashmap存储的数据(Node[])从新存储到newNode中
        for (int i = 0; i < node.length; i++) {//遍历诶个数组节点
            Node temp = node[i];
            while (temp != null) {//由于一个节点后可能存在其他链接的节点,所以需要进一步遍历每个节点
                int index = hashCode((K) temp.getKey());
                Node before = newNode[index];
                newNode[index] = temp;
                newNode[index].next = before;
                temp = temp.next;
            }
        }
        node = newNode;
    }

    //hash算法,简单除留余法
    private int hashCode(K key) {
        return key.hashCode() % DEFAULTSIZE;
    }

}

测试类:

/**
 * @author wolf
 * @create 2018-06-06    15:52
 */
public class Test {
    public static void main(String[] args) {

        wolfHashMap<String,String> wolfHashMap = new wolfHashMap<>();
        wolfHashMap.put("wolf", "haha");
        wolfHashMap.put("wolf", "haha");
        wolfHashMap.put("wolf", "haha");
        wolfHashMap.put("wolf", "haha");
        System.out.println(wolfHashMap.size());
        wolfHashMap.put("wolf1", "haha");
        System.out.println(wolfHashMap.size());
        System.out.println(wolfHashMap.get("1"));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_30585743/article/details/80597081