Hashtable、HashMap和TreeMap面试总结(持续更新......)

三者均实现了Map接口,存储的内容是基于key-value的键值对映射,一个映射不能有重复的键,一个键最多只能映射一个值。

1、元素特性

HashTable中的key、value都不能为null;

HashMap中的key、value可以为null,很显然只能有一个key为null的键值对,但是允许有多个值为null的键值对;

TreeMap中当未实现Comparator 接口时,key不可以为null;当实现Comparator接口时,若未对null情况进行判断,则key不可以为null,反之亦然。

2、顺序特性

HashTable、HashMap具有无序特性。

TreeMap是利用红黑树来实现的(树中的每个节点的值,都会大于或等于它的左子树种的所有节点的值,并且小于或等于它的右子树中的所有节点的值),实现了SortMap接口,能够对保存的记录根据键进行排序。

所以,一般需要排序的情况下是选择TreeMap来进行,默认为升序排序方式(深度优先搜索),可自定义实现Comparator接口实现排序方式。

3、初始化与增长方式

初始化时:

               HashTable在不指定容量的情况下的默认容量为11,且不要求底层数组的容量一定要为2的整数次幂;

               HashMap默认容量为16,且要求容量一定为2的整数次幂。

扩容时:

               Hashtable将容量变为原来的2倍加1

               HashMap扩容将容量变为原来的2倍

4、安全性方面、多线程应用环境比较:(重要)

HashTable:其方法函数都是同步的(采用synchronized修饰),不会出现两个线程同时对数据进行操作的情况,因此保证了线程安全性。也正因为如此,在多线程运行环境下效率表现非常低下。因为当一个线程访问HashTable的同步方法时,其他线程也访问同步方法就会进入阻塞状态。比如当一个线程在添加数据时候,另外一个线程即使执行获取其他数据的操作也必须被阻塞,大大降低了程序的运行效率,在新版本中已被废弃,不推荐使用。

HashMap:不支持线程的同步,即任一时刻可以有多个线程同时写HashMap;可能会导致数据的不一致。如果需要同步:

(1)可以用 Collections的synchronizedMap方法;

(2)使用ConcurrentHashMap类,相较于HashTable锁住的是对象整体, ConcurrentHashMap基于lock实现锁分段技术。首先将Map存放的数据分成一段一段的存储方式,然后给每一段数据分配一把锁,当一个线程占用锁访问其中一个段的数据时,其他段的数据也能被其他线程访问。ConcurrentHashMap不仅保证了多线程运行环境下的数据访问安全性,而且性能上有长足的提升。

5、Hash映射方面:(重要)

Hashtable:对于Hash表的选择更加高明,在计算Hash值时,直接使用对象的hashCode(hashCode是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值),然后再使用除留余数发来获得最终的位置。因为要计算除法,所以效率比较低。

HashMap:为了提高计算效率,将哈希表的大小固定为了2的幂,这样在取模预算时,不需要做除法,只需要做位运算。位运算比除法的效率要高很多(HashMap的效率虽然提高了,但是hash冲突却也增加了,为了解决这个问题,HashMap重新根据hashcode计算hash值后,又对hash值做了一些运算来打散数据。使得取得的位置更加分散,从而减少了hash冲突。当然了,为了高效,HashMap只做了一些简单的位处理。从而不至于把使用2的幂次方带来的效率提升给抵消掉。)

6、出现时间:(了解)

先有的Hashtable,后有的HashMap:

Hashtable:是java一开始发布时就提供的键值映射的数据结构,而HashMap产生于JDK1.2。虽然Hashtable比HashMap出现的早一些,但是现在Hashtable基本上已经被弃用了。而HashMap已经成为应用最为广泛的一种数据类型了。造成这样的原因一方面是因为Hashtable是线程安全的,效率比较低。

7、一段话总结 HashMap

HashMap:基于哈希思想,实现对数据的读写。

当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,让后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。

HashMap:使用链表来解决碰撞问题,当发生碰撞了,对象将会储存在链表的下一个节点中。

HashMap在每个链表节点中储存键值对对象。当两个不同的键对象的hashcode相同时,它们会储存在同一个bucket位置的链表中,可通过键对象的equals()方法用来找到键值对。如果链表大小超过阈值(TREEIFY_THRESHOLD, 8),链表就会被改造为树形结构

以上是本人对Hashtable和HashMap总结出的几点面试回答,关于两者的区别更详细的解答可以关注:

https://blog.csdn.net/wangxing233/article/details/79452946#commentBox

http://www.cnblogs.com/xinzhao/p/5644175.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值