hashMap 1.8版本:
底层是数组+链表+红黑树
数组中存的是对象(node)对象里面有key value 和 next 是指向下一个的标记 还有一个int 类型的hash值
hashmap插入链表的时候采用的是 尾插法。
需要找一个中间的平衡点, 当我们的数组长度小于平衡值 用链表, 大于平衡值用 红黑树
什么时候使用链表:当我们的链表的个数小于8 的时候使用链表
什么时候使用红黑树:当我们的链表个数大于8的时候就转成红黑树
为什么是链表个数是8 , 因为在源代码中了解到, 使用的是(泊松分布 poisson distribution)当链表个数是8 的时候 重复的概率是一亿个中只有6个重复的
链表和红黑树的转换:
当数组长度不够的时候怎么扩容: 会创建一个是原来2倍的数组 , len = 2的n次幂 原来的数据的 0.75f 倍
当我们的数组长度的扩容之后:
需要把原来的数据存在新的数组中, 需要今天判断当 我们的链表 hash & oldcap 等于0 放到原有的位置, 不等于0的时候就放早老数组加1的位置上,
当的数组是红黑树的时候: 就重新打乱重新放在新的数组中
hashMap 1.7 的理解:
hashMap 的底层是数组+ 链表, 又称为 链地址法。
HashMap 是继承了map的接口,允许null键和null值。map放入的值得顺序是无序的。 HashMap的线程是不安全的。
HashMap 需要重新计算 hash 值。
hashmap在取值的时候 get方面根据 key(hashcode)–>hash–>indexFor–>最终索引位置 e.hash == hash 没有必要 ,如果没这个判断可以可能到的数据是null的,
如果传入的key对象重写了equals方法却没有重写hashCode,而恰巧此对象定位到这个数组位置,如果仅仅用equals判断可能是相等的,但其hashCode和当前对象不一致,这种情况,根据Object的hashCode的约定,不能返回当前对象,而应该返回null。
对红黑树的理解:
主要就是recolor 标色 和 rotation 旋转 , 旋转分为 左旋转 和右旋转。
根节点 是黑色的 ; 相邻的父节点和子节点不能同时为红
hashMap 的遍历方法一:
效率高。
Map map = new HashMap(); Iterator iter = map.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); Object key = entry.getKey(); Object val = entry.getValue(); }
hashMap 遍历方法二:
效率低, 尽量不采用。
Map map = new HashMap(); Iterator iter = map.keySet().iterator(); while (iter.hasNext()) { Object key = iter.next(); Object val = map.get(key); }