java 关于HashMap的工作原理和优化

来源:互联网 发布:有意义的淘宝店铺名 编辑:程序博客网 时间:2024/05/18 03:16

 相信大家都用过HashMap,但是可能一些新手不知它的工作原理从而导致HashMap的性能非常糟糕!

为什么这么说呢?性能非常好的HashMap是什么情况下会导致性能下降那么多呢?

首先来说说HashMap的工作原理吧:

工作原理:

HashMap 是基于hashing(哈希算法)原理,调用者通过put()和get()方法获取对象。当调用者通过put()将键值对传过去,它调用键值对的hashCode方法来计算hashcode值,然后根据hashCode值找到bucket(桶)的位置来存储对象;当调用者通过get()方法获取对象时,通过键对象的equals()方法来找到对应的键值对,然后返回值对象;

HashMap 使用链表来解决解决hash“碰撞”问题,当发生“碰撞”时,将对象存储在链表的下一个节点。HashMap 在每个链表节点里存储的是键值对象。当两个不同的键对象的hashcode值相同,它们会存储在同一个bucket位置的链表中,获取值对象是会通过键的equals方法来知道键值对:


说到这,那么问题来了,“当两个值对象的hashCode值相等时会发什么?”

首先明确一点hashCode值相等并不能判断两个对象相等,如果两个不同的对象hashCode 值相等,所以在存储的时候发生了“碰撞”,因为hashCode值相等,所以存储在相同位置的bucket的链表中,最坏的情况所有的对应都存储在同一个位置的bucket中的链表中,这样HashMap 就退化成了一个链表,查找数据时查找时间从O(1)到O(n),大大降低了HashMap的性能,在这种情况下你就应该考虑是否继续使用HashMap?

那么问题又来了,对于上述问题如何优化?

优化上述的办法就是减少“碰撞”,如何减少“碰撞”?

1.String, Interger这样的wrapper类作为HashMap的键;而且String最为常用,因为String是不可变的,也是final的,而且已经重写了equals()和hashCode()方法了。其他的wrapper类也有这个特点。不可变性是必要的,因为为了要计算hashCode(),就要防止键值改变

2.使用自定义的对象作为键时遵守重写equals()和hashCode()方法的规则,保证不同的对象不要出现相同的hashCode;

好了,对于提高HashMap的建议就这些吧,希望能帮助需要的朋友们!!!

友情提示:java 8 已经对HashMap的性能提升

0 0
原创粉丝点击