HashMap是Java中的一个重要的数据结构!html
与HashMap更重要的一个数据结构是HashTable,其中最重要的区别是HashTable传说中是线程安全的(之因此说他是传说是由于我并无去理解为何,这是个人错,没有理解就搬上了讲台!)java
HashMap的内部结构很简单,以下(图片来自importnews,专属java的一个实时blog.本文也必定程度上参考了importnews,之全部没有直接转载是由于我以为,有些东西,你只是看到了,他并不属于你!而我要作的,就是消化它,达到能够有本身看法的地方,原文连接地址:http://www.importnew.com/10620.html)数组
在HashMap内部,实现存贮key-value键值对的是一个Entity的内部类,安全
static class Entry implements Map.Entry { final K key; V value; Entry next; final int hash; ...//More code goes here } `
这个类能够构成一个链表,在key中的hashCode相同时,会构成一个链表,数据结构
这个类在HashMap中构成了一个table数组,全部的键值对就保留在这个键值对数组之中,这个数据默认的长度是16,当数据超过这个大小以后,会自动的真正增加,可是若是数据刚恰好处于增加的上边缘,也就是>=,会形成数据内存大浪费,一些文章推荐咱们在使用一些集合类的时候要指定好它的大小,避免形成过大的内存泄漏函数
从咱们日常使用的HashMap中咱们能够得出,操纵HashMap只是经过put和get方法post
1.了解put方法this
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); 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; }
对key作null检查。若是key是null,会被存储到table[0],由于null的hash值老是0。spa
key的hashcode()方法会被调用,而后计算hash值。hash值用来找到存储Entry对象的数组的索引。有时候hash函数可能写的 很很差,因此JDK的设计者添加了另外一个叫作hash()的方法,它接收刚才计算的hash值做为参数。若是你想了解更多关于hash()函数的东西,可 以参考:hashmap中的hash和indexFor方法线程
indexFor(hash,table.length)用来计算在table数组中存储Entry对象的精确的索引。
在咱们的例子中已经看到,若是两个key(这里指的是两个不一样key值)有相同的hash值(也叫冲突),他们会以链表的形式来存储。因此,这里咱们就迭代链表。
2.了解get
public V get(Object key) { if (key == null) return getForNullKey(); int hash = hash(key.hashCode()); for (Entry<k , V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) return e.value; } return null; }
你传递一个key从hashmap总获取value的时候:
对key进行null检查。若是key是null,table[0]这个位置的元素将被返回。
key的hashcode()方法被调用,而后计算hash值。
indexFor(hash,table.length)用来计算要获取的Entry对象在table数组中的精确的位置,使用刚才计算的hash值。
在获取了table数组的索引以后,会迭代链表,调用equals()方法检查key的相等性,若是equals()方法返回true,get方法返回Entry对象的value,不然,返回null。
总结: