深入理解HashMap

一、数据结构

        java集合主要是两个接口中衍生而来。一个是Collection,另一个就是是Map。两个接口都来自java.util包。HashMap实现了Map接口,其底层是数组加单链表的方式进行存储的。

        具体来说,在执行put(key,value)方法后,先key的hash值。通过key.hashCode()方法 后在经过扰动函数得到hash值。(数组长度 - 1) & hash后得到数组的下标。若该位置为空,则直接放入;若该位置不为空,则需要比较他们的hash值。若与某个相同,则再用equals方法比较他们的地址值是否相等。若为false则采用拉链法解决哈希冲突,为true则替换该位置的value值。

二、方法 

 1、put方法

 

package com.tyz.hashmap;


public class HashMap<K,V> {

    static final int hash(Object key){
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

    public V put(K key,V value){
        return putVal(hash(key),key,value,false,true);
    }

    final V putVal(int hash,K key,V value,boolean onlyIfAbsent,boolean evict) {
        Node<K, V>[] tab;
        Node<K, V> p;
        int n, i;
        //判断是否为空,为空就初始化,不为空就对tab和n进行赋值
        if (tab == null) {
            n = (tab = resize()).length;
        }
        //根据hash值计算出数组下标位置
        //如果该位置为空,则直接赋值
        if ((p = tab[i = (n - 1) & hash]) == null) {
            tab[i] = newNode(hash, key, value, null);
            //如果不为空,则需要判断二者的hash值和key是否相等
        } else {
            Node<K, V> e;
            K k;
            if (p.hash == hash && ((k == p.key) == key || (key != null && key.equals(k)))) {
                //如果相等则覆盖原值
                e = p;
            } else {
                //二者不相同,则但是数组中已经有value了,所以需要遍历单链表进行尾插。
                for(int binCount = 0;;++binCount){
                    if((e = p.next) == null){
                        p.next = newNode(hash,key,value,null);
                        break;
                    }
                    if(e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))){
                        break;
                    }
                    p = e;
                }
            }
            //这种属于覆盖操作,当e中有值进入操作
            if (e != null) { // existing mapping for key
                //oldValue保存老的值,方便return
                V oldValue = e.value;
                //onlyIfAbsent传入的是false,指定能进入判断
                if (!onlyIfAbsent || oldValue == null)
                    //新元素的值将老元素的值覆盖掉
                    e.value = value;
                //HashMap提供给子类的方法
                afterNodeAccess(e);
                //put操作有返回值,返回的是插入之前已经存在的元素的value值
                return oldValue;
            }
        }
        //增加修改次数
        ++modCount;
        if(++size > threshold){
            resize();
        }
        afterNodeInsertion(evict);
        return null;
    }

}

2、待续

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值