Hashtable、HashMap、TreeMap

Hashtable、HashMap、TreeMap之间有什么异同?

  • 都是以键值对的形式存储和操作数据的容器类型。
  • HashTable 由早期Java类库提供的一个哈希表实现,是线程安全的,不支持 null 键和值 。出于同步导致的性能开销,已经很少被推荐使用。
  • HashMap 由应用更加广泛的哈希表实现,基本上与 HsahTable 相同,但不是线程安全的,且支持 null 键和值。通常进行 put 或 get 操作时,其时间复杂度为 O(1) ,所以其是绝大部分利用键值对存取场景的首选
  • TreeMap是基于红黑树的一种提供顺序访问的Map,其时间复杂度一般是 O(log(n))的。具体顺序可有指定的 Comparator 来决定,或根据键的自然顺序来判断。TreeMap中当未实现 Comparator 接口时,key 不可以为null;当实现 Comparator 接口时,若未对null情况进行判断,则key不可以为null,反之亦然。
关于初始化容量与扩容机制
  • 初始化时:
    HashTable在不指定容量的情况下默认容量为 11 ,且不要求底层数组的容量一定要为 2 的整数次幂;
    HashMap 默认容量为 16 ,且要求容量一定为 2 的整数次幂。
  • 扩容时:
    HashTable 将容量变为原来的2倍加1;
    HashMap将容量变为原来的两倍。
有关线程安全性
  • HashTable 其方法函数都由 synchronized 修饰
  • HashMap 需要支持同步时:
    1)使用 Collections 的 synchronizedMap 方法;
    2)使用 基于 lock 实现锁分段的 ConCurrentHashMap 类(存放的数据分成一段一段的存储方式,然后给每一段数据分配一把锁,当一个线程占用锁访问其中一个段的数据时,其他段的数据也能被其他线程访问。ConcurrentHashMap不仅保证了多线程运行环境下的数据访问安全性,而且性能上有长足的提升。);
HashMap 出现哈希碰撞时是怎么处理的?

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

常见的哈希冲突解决方法?
  • 开放地址法:
    当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈希地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈希地址p2,…,直到找出一个不冲突的哈希地址pi ,将相应元素存入其中。
  • 再哈希法:
    这种方法是同时构造多个不同的哈希函数:
    Hi=RH1(key) i=1,2,…,k
    当哈希地址Hi=RH1(key)发生冲突时,再计算Hi=RH2(key)……,直到冲突不再产生。这种方法不易产生聚集,但增加了计算时间。
  • 链地址法:
    将所有哈希地址为i的元素构成一个称为同义词链的单链表,并将单链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。链地址法适用于经常进行插入和删除的情况。
  • 建立公共溢出区:
    将哈希表分为基本表和溢出表两部分,凡是和基本表发生冲突的元素,一律填入溢出表。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值