HashMap和HashTable的区别

HashMap

Java HashMap 底层采用哈希表结构(数组+链表、JDK1.8后为数组+链表或红黑树)实现,结合了数组和链表的有点:

  1. 数组有点:通过组下标可以快速实现对数组元素的访问,效率极高。
  2. 链表有点:插入或删除数据不需要移动元素,只需修改节点引用,效率极高。

HashMap 通过hash 方法计算key的哈希码,然后通过(n-1)&hash公式(n为数组长度)得到key在数组中存放的下标。当两个key在数组中存放的下标一致时,数据将以链表的方式存储(哈希冲突,哈希碰撞)。在链表中查找数据必须从第一个元素开始一层一层往下找,直到找到为止,时间复杂度为O(N),所以当链表长度越来越长时,HashMap的效率越来越低。
JDK1.8采用数组+链表+红黑树结构来实现HashMap。当链表中的元素超过8个并且数组长度大于64,会将链表转换为红黑树,转换后数据查询时间复杂度为O(logN)。

put操作过程总结:

  1. 判断HashMap数组是否为空,是的话初始化数组。(在创建HashMap对象的时候并不会直接初始化数组);
  2. 通过(n-1)&hash计算key在数组中的存放索引;
  3. 目标索引位置为空的话,直接创建Node存储(红黑树节点使用TreeNode);
  4. 目标索引位置不为你空的话,分下面三种情况
    key相同,覆盖旧值
    该节点类型是红黑树的话,执行红黑树插入操作
    该节点类型是链表的话,遍历到最后一个元素尾插入,如果期间遇到有相同key,则直接覆盖。如果链表长度大于等于8并且数组容量大于等于64,则将链表转换为红黑树结构。
  5. 判断HashMap元素个数是否大于等于threshold,是的话,进行扩容操作。

HashTable

HashTable是Map接口线程安全实现版本,数据结构和方法实现与HashMap类似。
put添加指定键值对,键和值都不能为null

HashTable和HashMap对比

  1. 线程是否安全:HashMap是线程不安全的,HashTable是线程安全的。
  2. 对Null key 和Null value的支持:HashMap中,null可以作为健,这样的健只有一个,可以有一个或多个键所对应的值为null;HashTable中key和value都不能为null,否则抛出空指针异常;
  3. 初始容量大小和每次扩容量大小的不同:创建时如果不指定容量初始值,HashTable默认的初始大小为11,之后每次扩容,容量变为原来的2n+1。HashMap默认的初始化大小为16,之后每次扩容,容量变为原来的2倍;
    创建时如果给定了容量初始值,那么HashTable会直接使用你给给定的大小,HashMap会将其 扩充为2的幂次方大小。
  4. 底层数据结构:JDK1.8及以后的HashMap在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认8)时,将链表转化为红黑树,以减少搜索时间,HashTable没有这样的机制。

HashSet

HashMap的key是不允许重复的,这也正好符合Set的特性。因为HashSet内部采用HashMap存储数据,所以HahSet可以存储null值,支持快速失败,非线程安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HashMapHashtable 都是用于存储键值对的数据结构,它们在功能上非常相似,但也存在一些区别。 1. 线程安全性:Hashtable 是线程安全的,即多个线程可以同时访问一个 Hashtable 实例而不需要额外的同步措施。而 HashMap 不是线程安全的,如果多个线程同时访问一个 HashMap 实例,可能会导致数据不一致的问题。如果需要在多线程环境下使用,可以考虑使用 ConcurrentHashMap。 2. null 键和 null 值:Hashtable 不允许键或值为 null,如果尝试将 null 键或 null 值放入 Hashtable 中,会抛出 NullPointerException。而 HashMap 允许键和值为 null,可以正常存储和获取 null 值。 3. 继承关系:Hashtable 是 Dictionary 类的子类,而 HashMap 是 AbstractMap 类的子类。由于继承关系的不同,导致它们在实现上有一些差异。 4. 迭代顺序:HashMap 不保证迭代顺序,即遍历 HashMap 的键值对时,不一定按照插入顺序或者其他顺序进行遍历。而 Hashtable 的迭代顺序是按照插入顺序进行的。 5. 性能:由于 Hashtable 是线程安全的,它在多线程环境下的性能可能会受到一定影响。而 HashMap 在单线程环境下的性能通常会更好。 总的来说,如果在单线程环境下使用,并且需要允许键或值为 null,可以优先选择使用 HashMap。如果在多线程环境下使用,或者需要保证迭代顺序,可以考虑使用 Hashtable
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值