Java之HashMap学习

来源:互联网 发布:c语言如何调用opencv 编辑:程序博客网 时间:2024/05/18 01:50

HashMap是Hashtable的轻量级的实现,采用数据结构中的哈希表进行存储,遇到冲突时,采用拉链法解决冲突。

HashMap中有一个Entry[capacity]数组,Entry即为map中一个存储类,其中有成员key,value,next,next指向下一个同义词的Entry。

几个关键的属性

存储数据的数组

transient Entry[] table; 
默认容量

static final int DEFAULT_INITIAL_CAPACITY = 16;

最大容量

 static final int MAXIMUM_CAPACITY = 1 << 30;

默认加载因子,加载因子是一个比例,当HashMap的数据大小>=容量*加载因子时,HashMap会将容量扩容

static final float DEFAULT_LOAD_FACTOR = 0.75f;

当实际数据大小超过threshold时,HashMap会将容量扩容,threshold=容量*加载因子

int threshold;

加载因子

final float loadFactor;

寻址时,采用key的哈希值(通过一种算法对其hash值进行了运算)model table表的长度,得到相应的值。

插入时,在哈希表中遍历此值对应的链表,如果有相同的key值则替换其value值,如果没有则插入在表头。

    public V put(K key, V value) {        if (key == null)            return putForNullKey(value);        int hash = hash(key);        int i = indexFor(hash, table.length);        for (Entry<K,V> e = table[i]; e != null; e = e.next) {            Object k;            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {                V oldValue = e.value;                e.value = value;                e.recordAccess(this);                return oldValue;            }        }        modCount++;        addEntry(hash, key, value, i);        return null;    }


    indexFor方法,其中table的length初始值为16,最大值为1<<30(2^29),而table的容量扩充是通过左移来实现的,所以h&(length-1)相当于mod length

    static int indexFor(int h, int length) {        return h & (length-1);    }


如put代码所示,当hashmap中有此key时,替换掉原来的value,如果没有此key,则添加此Key,调用addEntry(hash,key,value,i)

    void addEntry(int hash, K key, V value, int bucketIndex) {        //数量大于装载因子,进行扩容        if ((size >= threshold) && (null != table[bucketIndex])) {            resize(2 * table.length);            hash = (null != key) ? hash(key) : 0;            bucketIndex = indexFor(hash, table.length);        }        createEntry(hash, key, value, bucketIndex);    }

//往table中添加此key,相当于在链表表头插入该元素。(new Entry<>(hash,key,value,e) e参数为next)  void createEntry(int hash, K key, V value, int bucketIndex) {        Entry<K,V> e = table[bucketIndex];        table[bucketIndex] = new Entry<>(hash, key, value, e);        size++;    }



HashMap与Hashtable主要的区别在于,HashMap允许空(null)键值(key)和空value值,Hashtable是线程安全的。

0 0
原创粉丝点击