一步一步解析java集合框架HashMap源码(1)

来源:互联网 发布:vb自学网站 编辑:程序博客网 时间:2024/05/10 23:28

首先看如何简单实用HashMap

    public static void main(String[] args) {        Map<String,String> map=new HashMap<String,String>();        map.put("firstKey","firstValue");        map.put("secondKey","secondValue");    }
  • 首先查看HashMap的属性
    /**     * 默认的初始化容量16     */    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 乘以16(2的4次方)    /**     * 最大容量     */    static final int MAXIMUM_CAPACITY = 1 << 30;    /**     * 加载因子     */    static final float DEFAULT_LOAD_FACTOR = 0.75f;    /**     * 散列表的加载因子     */    final float loadFactor;    /**     * 存储键值对集合Node<K,V>数组     */    transient Node<K,V>[] table;    /**     * 键值对数     */    transient int size;
  • 默认构造函数
    public HashMap() {        this.loadFactor = DEFAULT_LOAD_FACTOR;     }
  • 添加数据
    /**     * 添加键值对     */    public V put(K key, V value) {        return putVal(hash(key), key, value, false, true);    }
    /**     * 获取hash值     */    static final int hash(Object key) {        int h;        //通过运算符计算得到一个hash值        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);    }

这里调用了Object的hashCode()方法,只是个原生函数,java自身并没有实现,由C++语言进行实现,java只管调用。

public native int hashCode();
    /**     * @param hash hash值     * @param key 键     * @param value 值     */    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                   boolean evict) {        Node<K,V>[] tab; Node<K,V> p; int n, i;        //默认构造函数,table==null        if ((tab = table) == null || (n = tab.length) == 0)        //resize();初始化散列表table            n = (tab = resize()).length;//16        //(n - 1) & hash计算索引        if ((p = tab[i = (n - 1) & hash]) == null)            tab[i] = newNode(hash, key, value, null);//构造新的节点,添加进集合        else {            Node<K,V> e; K k;            if (p.hash == hash &&                ((k = p.key) == key || (key != null && key.equals(k))))                e = p;            else if (p instanceof TreeNode)                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);            else {                for (int binCount = 0; ; ++binCount) {                    if ((e = p.next) == null) {                        p.next = newNode(hash, key, value, null);                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st                            treeifyBin(tab, hash);                        break;                    }                    if (e.hash == hash &&                        ((k = e.key) == key || (key != null && key.equals(k))))                        break;                    p = e;                }            }            if (e != null) { // existing mapping for key                V oldValue = e.value;                if (!onlyIfAbsent || oldValue == null)                    e.value = value;                afterNodeAccess(e);                return oldValue;            }        }        ++modCount;        if (++size > threshold)            resize();        afterNodeInsertion(evict);        return null;    }//没有实体,空的函数    void afterNodeInsertion(boolean evict) { }

关注下面两点:

    public static void main(String[] args) {        Map<String,String> map=new HashMap<String,String>();        map.put("firstKey","firstValue");        map.put("secondKey","secondValue");        String first="firstKey";        String second="secondKey";        System.out.println(hash(first));//-549860682        System.out.println(hash(second));//-817573361        System.out.println(getIndex(hash(first)));//6        System.out.println(getIndex(hash(second)));//15    }    static int getIndex(int hash){        return 15&hash;    }    static final int hash(Object key) {        int h;        //通过运算符计算得到一个hash值        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);    }

第一次添加数据map.put(“firstKey”,”firstValue”);
需要resize();初始化table为容量16的数组;table[6]=new Node(…)
第二次添加数据不需要resize();table[15]=new Node(…);

    public static void main(String[] args) {        Map<String,String> map=new HashMap<String,String>();        map.put("firstKey","firstValue");        map.put("secondKey","secondValue");        map.put("fir","thirdValue");        map.put("first","fourthValue");        String first="firstKey";        String second="secondKey";        String third="fir";        String fourth="first";        System.out.println(hash(first));//-549860682        System.out.println(hash(second));//-817573361        System.out.println(hash(third));//101390        System.out.println(hash(fourth));//97441662        System.out.println(getIndex(hash(first)));//6        System.out.println(getIndex(hash(second)));//15        System.out.println(getIndex(hash(third)));//14        System.out.println(getIndex(hash(fourth)));//14    }

添加了相同索引的数据

    /**     * @param hash hash值     * @param key 键     * @param value 值     */    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,                   boolean evict) {        Node<K,V>[] tab; Node<K,V> p; int n, i;        //默认构造函数,table==null        if ((tab = table) == null || (n = tab.length) == 0)            //resize();初始化散列表table            n = (tab = resize()).length;//16        //(n - 1) & hash计算索引        if ((p = tab[i = (n - 1) & hash]) == null)            tab[i] = newNode(hash, key, value, null);//构造新的节点,添加进集合        else {            Node<K,V> e; K k;            if (p.hash == hash &&                ((k = p.key) == key || (key != null && key.equals(k))))                e = p;            else if (p instanceof TreeNode)//false                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);            else {                for (int binCount = 0; ; ++binCount ) {                    if ((e = p.next) == null) {                         //以链表形式添加进散列表,构造新节点指定next                       **p.next = newNode(hash, key, value, null);**                        if (binCount >= TREEIFY_THRESHOLD - 1) //TREEIFY_THRESHOLD=8                            treeifyBin(tab, hash);                        break;//跳出整个循环                    }                    if (e.hash == hash &&                        ((k = e.key) == key || (key != null && key.equals(k))))                        break;                    p = e;                }            }            if (e != null) { // existing mapping for key                V oldValue = e.value;                if (!onlyIfAbsent || oldValue == null)                    e.value = value;                afterNodeAccess(e);                return oldValue;            }        }        ++modCount;        //第一次添加数据,threshold=12,        if (++size > threshold)            resize();        afterNodeInsertion(evict);        return null;    }
0 0
原创粉丝点击