主要介绍HashMap的一些特性,以及面试中会遇到的一些问题。
1、java的HashMap
HashMap是java集合框架中的一员。采用的是数组与链表的结构,两种数据结构都用到了。数组随机访问,链表方便添加元素。
2、HashMap的结构
HashMap里面有个成员变量叫做 table,类型是Entry[]。Entry是HashMap的内部类。Entry有个成员变量就做next,如果put的
时候经过计算得到需要放置的位置已经存在数据了,则通过equalse比较是否一样。如果不一样就把next指向另外一个值,这样就
解决了碰撞的问题。理想情况下,table数据一个位置上只放一个键值对。
3、HashMap的put过程
1、计算key的hashCode,比如得到了1000,然后与table这个数组的长度做与运算得到6,于是就把这个数据存放到table[6]这个位置。
2、取出的时候与存放一样,得到hashCode在与运算,然后就知道存放到哪里了。所以理想情况下HashMap的时间复杂度是一次命中。
3、从中可以看出,数据存到那个位置与hashCode有关系。那么如果存放同一个位置,旧数据是怎么处理的呢。
4、HashMap如何存放hashCode值相同的数据
1、比如我put两个数据,可以是 “key1","key2" 恰好他们经过运算都是放到了table[3]这个位置,那么会比较key1.equalse(key2),
如果一样,说明是同一个对象,则覆盖。并且put方法会返回这个旧值。
2、如果调用equalse之后发现他们不同,则Entry的next将会引用另外一个数据,于是两个对象就像链一样连接起来。get的时候
经过hashCode计算放哪里,通过equalse判断取出哪个值。
5、需要注意的问题
1、HashMap的put时,需要hashCode与equalse。所以你经常会看到,要实现hashCode与equalse方法这条编程建议。
2、如果有个HashMap往里面不停放值,同时key这个对象是我们定义的。而涉及到hashCode的字段运算被我们改了,那么这个
值就可能再也取不出来了。
3、HashMap是线程不安全的,原因就是没有同步,同时分配内存时。table数据默认是16个大小的,数据存的多自然不够用,
扩容时很容易导致Entry的next相互引用。于是出现死循环,这样就GG了。
4、如果有疑问,以及我说的不对的。可以留言在下面,我们一起进步。