自己动手实现集合框架类(三)之HashMap

来源:互联网 发布:开启服务器端口 编辑:程序博客网 时间:2024/05/22 02:07

  HashMap的底层实现主要是基于数组和链表来实现的,HashMap中通过key的hashCode来计算hash值的,由这个hash值计算在数组中的位置,将新插入的元素放到数组的这个位置,如果新插入的元素的hash值跟这个位置上已有元素的hash值相同,就会出现hash冲突,这时候,就在该位置通过链表来插入新的元素。

这里懒的画图了,借鉴http://www.cnblogs.com/chengxiao/p/6059914.html的图说明一下HashMap的底层数组加链表的结构。

这里写图片描述

我在图中标注了红色的框表示数组的结构,只有出现hash冲突的时候(横排数组位置已经有元素占了),才会在该位置通过链表的形式插入新元素,也是紫色的方框。

Map接口类:

package com.java.myutil;public interface Map {    int size();    boolean isEmpty();    Object get(Object key);    Object put(Object key, Object value);    interface Entry{        Object getKey();        Object getValue();    }}

HashMap的实现:

package com.java.myutil;/** * 数组加链表的结构 */public class HashMap implements Map {    //默认容量16   private final int DEFALUT_CAPACITY=16;   //内部存储结构,数组   Node[] table=new Node[DEFALUT_CAPACITY];   private int size=0;   public int size() {        return size;   }    public boolean isEmpty() {        return size==0;    }    public Object get(Object key) {        int hashValue=hash(key);        int i=indexFor(hashValue, table.length);        for (Node node = table[i]; node!=null; node=node.next) {           if (node.key.equals(key)&&hashValue==node.hash) {               return node.value;          }        }        return null;    }    public Object put(Object key,Object value) {        //通过key,求hash值        int hashValue=hash(key);        //同过hash值,找到这个key应该放在数组的哪个位置(i)        int i=indexFor(hashValue,table.length);        //i位置已经有数据了        for (Node node = table[i]; node!=null; node=node.next) {            Object k;            //且数组中已有这个key的,覆盖其原始的value            if (node.hash==hashValue&&((k=node.key)==key||key.equals(k))) {                Object oldValue=node.value;                node.value=value;                return oldValue;            }        }        //如果i位置没有数据,或者i位置有数据,但是key是新的key,则新增节点        addEntry(key, value, hashValue, i);        return null;    }    public void addEntry(Object key, Object value, int hashValue, int i) {        //如果超过了数组原始的大小,则扩大数组        if (++size==table.length) {            Node [] newTable=new Node[table.length*2];            System.arraycopy(table, 0, newTable, 0, table.length);            table=newTable;        }        //得到i位置的数据        Node eNode=table[i];        //新增节点,将该节点的next值指向前一个节点        table[i]=new Node(hashValue, key, value, eNode);        /*         * 上面两句话,需要注意的是,如果i位置原始位置table[i]没有值,         * eNode为空,就直接将新的node放入table[i],并将该node的next指向空新的node插入到原始node的前面,所以新的node的next指向原始位置i的node         */    }    public int indexFor(int hashValue, int length) {        return hashValue%length;    }    public int hash(Object key) {        return key.hashCode();    }    static  class Node implements Map.Entry{        int hash;        Object key;        Object value;        Node next;//指向下一个节点        Node(int hash, Object key, Object value, Node next) {                this.hash = hash;                this.key = key;                this.value = value;                this.next = next;            }        public Object getKey() {            return key;        }        public Object getValue() {            return value;        }    }    public static void main(String[] args) {        HashMap hashMap=new HashMap();        hashMap.put("aaa", "1111");        hashMap.put("bbb", "2222");        hashMap.put("ccc", "3333");        hashMap.put("ddd", "4444");        hashMap.put("eee", "5555");        hashMap.put("ffff", "9666");        hashMap.put("ggg", "geg");        System.out.println(hashMap.get("ggg"));    }}
阅读全文
1 0
原创粉丝点击