hashmap允许null key和value ,属于fail-fast,因此会抛出ConcurrentModificationException异常。当存储过多数据时,就会转成红黑树进行存储,就像java.util.TreeMap。内部维护的是一个node数组。
给hashmap进行put数据时,首先判断hashmap是否为空,为空则直接存储;不为空则从数组从最后往前遍历判断数组是否有相同的值,如果key有相同的hash值,则替换;否则判断在数组中的这个对象类型是否是树形结构,是的话调用红黑树进行存储;否则调用链表进行处理,在链表处理的过程中,如果链表的长度大于等于2>>3 -1,则转红黑树存储。调用put方法时,如果发现目前的bucket占用程度已经超过了loadFactor,就会发生resize。简单的说就是把bucket扩充为2倍,之后重新计算index,把节点再放到新的bucket中。当超过限制的时候会resize,又因为我们使用的是2次幂的扩展,所以,元素的位置要么是在原位置,要么是在原位置再移动2次幂的位置
HashMap的工作原理:
通过hash的方法,通过put和get存储和获取对象。存储对象时,我们将K/V传给put方法时,它调用hashCode计算hash从而得到bucket位置,进一步存储,HashMap会根据当前bucket的占用情况自动调整容量(超过Load Facotr则resize为原来的2倍)。获取对象时,我们将K传给get,它调用hashCode计算hash从而得到bucket位置,并进一步调用equals()方法确定键值对。如果发生碰撞的时候,Hashmap通过链表将产生碰撞冲突的元素组织起来,在Java 8中,如果一个bucket中碰撞冲突的元素超过某个限制(默认是8),则使用红黑树来替换链表,从而提高速度。