了解学习HashMap

        基本上我们在面试都会问关于hashMap底层原理,是因为我们在企业开发中都会用到hashMap这个对象,相比较我们创建一个类来讲,使用hashMap来装载参数或者结果集合会更方便一些。那么如何创建或者说使用它的效率更高呢。

  其实我们在创建hashMap对象的时候很少会给他设置一个默认值【Hashmap他的默认初始容量为16,加载因子为0.75,这就好比说你的长度为16,最多只能装载12个长度,另外关于hashMap碰撞的问题,他能装载的长度会更少】,

hashMap组成结构=数组+链表(每一个元素存储的是一个链表的头结点,当碰撞的概率越多,链表越长,最早放的元素查询的时间复杂数越大,组成链表结点其实是hashmap内部定义的一个类:entity=key+value+next指向下一个元素)

数组:存储区间连续,占用内存严重,寻址容易,但是插入,删除困难;

链表:存储区间离散,占用内存比较宽松。实现困难,插入删除容易。 hashmap结合了两种数据结构。实现了寻址容易,插入,删除也容易。

数组的查询效率是O(1) ,链表的是时间复杂度为O(n) , 二叉树的查找、插入的时间复杂度较低是O(logN);

hash碰撞是因为在进行hash 计算的时候通过&计算【hash计算有通过长度n &(n-1)】,例如说1(001)与7(111)通过&计算就会得到 001(1)这样就会导致值相等,发生哈希碰撞,一般发生hash碰撞的在jdk1.7版本以前都是放在链表上。如图所示

在1.7版本以上添加了树的理论,这样在查询效率上面会提高不少【当二叉查询树变成一条链表效率最差。所以有AVL平衡树 限制节点深度差不超过1,避免产生链表一般的树。】,关于上面提到hash碰撞文档,如何避免和这说减少hash碰撞呢。最佳的方法就是length-1 的二进制全部为1,设置length=2^n【将hash表的长度设置为2的n次方】,那么所以的哈系桶都有可能被使用。例如说美团以前一道面试题长度为100 ,初始化化hash的容量多少合适:首先根据加载因子0.75计算为133.3,向上取整为134.与134最靠近的2^n无疑是128,但是这样修改了hashmap长度但是没有修改加载因子的话,当超过了默认长度的话hashMap会进行rehash操作,这样代价就会很大,不可取。

所以我们可以设置长度为128*2=256.这样就会由于空间的加大和有效的利用哈系桶,大大降低了碰撞,读取效率提高。

扫描二维码关注公众号,回复: 4874359 查看本文章

在初始化hash的长度时候根据自己的需要设置需要的长度,减小开销。优化从每一小步开始。

           目前就想到这些,以后如果有补充再修改。

           不知道其中的内容的正确性,若有错误,请留言指出,避免误导别人。

猜你喜欢

转载自blog.csdn.net/shenmerenya/article/details/86293765