面试经验——HashTable、HashMap、TreeMap

HashMap

  1. HashMap由数组+链表+红黑树组成,当链表当元素个数大于8时链表存储就变为了红黑树存储,当小于6时会变回去。
    2. 初始容量大小(默认是16)和加载因子(默认是0.75f),一旦数组中存储的元素个数超过初始容量*加载因子时就会调用rehash方法将数组容量增加到原来的两倍(扩容);在做扩容的时候会生成一个新的数组,原来的所有数据需要重新计算哈希码值重新分配到新的数组,所以扩容的操作非常消耗性能。
    3. put()的实现:1)首先将k,v封装到Node对象当中。2)它的底层会调用K的hashCode()方法得出hash值。3)通过哈希表函数/哈希算法,将hash值转换成数组的下标,下标位置上如果没有任何元素,就把Node添加到这个位置上。如果说下标对应的位置上有链表。此时,就会拿着k和链表上每个节点的k进行equal。如果所有的equals方法返回都是false,那么这个新的节点将被添加到链表的末尾。如其中有一个equals返回了true,那么这个节点的value将会被覆盖。
    4. get()的实现:1)先调用k的hashCode()方法得出哈希值,并通过哈希算法转换成数组的下标。2)通过上一步哈希算法转换成数组的下标之后,在通过数组下标快速定位到某个位置上。重点理解如果这个位置上什么都没有,则返回null。如果这个位置上有单向链表,那么它就会拿着参数K和单向链表上的每一个节点的K进行equals,如果所有equals方法都返回false,则get方法返回null。如果其中一个节点的K和参数K进行equals返回true,那么此时该节点的value就是我们要找的value了,get方法最终返回这个要找的value。

HashMap是线程安全的吗

HashMap不是线程安全的,在添加数据的时候,会根据key和value计算出在底层数组中的位置,然后封装成entrey对象插入,但由于HashMap并没有做对应的线程安全处理,所以如果恰好两个线程同时操作的话,就有点会将其中一个数据覆盖掉,这不符合要求。 那么解决方法就是说,你可以在操作这个HashMap的时候手动的上锁,可以通过Lock也可以通过synchronized关键字。当然我更推荐直接使用java已经提供了的ConcurrentHashMap,其内部使用了Lock来解决线程安全问题,并且底层结构也进行了一些变动,上锁的时候只会锁对应下标的元素,不会对其他位置造成影响,即保证了线程安全,又保证了性能。

HashMap 与 HashTable 有什么区别

  1. 线程安全: HashMap 是非线程安全的,HashTable 是线程安全的;HashTable 内部的方法基本都经过 synchronized 修饰。(要保证线程安全的话就使用ConcurrentHashMap );
  2. 效率: 因为线程安全的问题,HashMap 要比 HashTable 效率高一点。HashTable 基本被淘汰,不要在代码中使用它;
  3. Hashtable的key、value都不能为null;HashMap的key、value可以为null,不过只能有一个key为null,但可以有多个null的value。
  4. 底层数据结构:JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间。Hashtable 没有这样的机制。

HashTable、HashMap、TreeMap的区别(待完善)

  1. HashMap是继承自AbstractMap类,而HashTable是继承自Dictionary类。不过它们都同时实现了map、Cloneable(可复制)、Serializable(可序列化)这三个接口。存储的内容是基于key-value的键值对映射,不能有重复的key,而且一个key只能映射一个value。HashSet底层就是基于HashMap实现的。
  2. Hashtable与TreeMap的key、value都不能为null;HashMap的key、value可以为null,不过只能有一个key为null,但可以有多个null的value。
  3. Hashtable、HashMap具有无序特性。TreeMap是利用红黑树实现的(树中的每个节点的值都会大于或等于它的左子树中的所有节点的值,并且小于或等于它的右子树中的所有节点的值),实现了SortMap接口,能够对保存的记录根据键进行排序。所以一般需求排序的情况下首选TreeMap,默认按键的升序排序(深度优先搜索),也可以自定义实现Comparator接口实现排序方式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值