HashTable 和 HashSet理解

# HashTable

HashMap和HashTable是两种不同的哈希表数据结构,它们在多个方面有所不同:

**数据结构:**

HashMap和HashTable都使用哈希表来存储键值对。在数据结构上是基本相同的,都创建了一个继承自Map.Entry的私有的内部类Entry,每一个Entry对象表示存储在哈希表中的一个键值对。

Entry对象唯一表示一个键值对,有四个属性:

-K key 键对象

-V value 值对象

-int hash 键对象的hash值

-Entry entry 指向链表中下一个Entry对象,可为null,表示当前Entry对象在链表尾部


 

**线程安全性**

HashTable是线程安全的,这意味着所有方法都是同步的,因此在多线程环境下使用HashTable时不需要额外的同步措施,但这也降低了性能;HashMap不是线程安全的,因此在多线程环境下使用它时必须手动同步,或者使用Collections.synchronizedMap()方法来获得线程安全的实现。

**Null值**

HashTable不允许键或值为null,而HashMap允许键和值为null。

**继承和实现**

都是Map接口的实现

HashMap继承自AbstractMap类,实现了Map接口;HashTable继承自Dictionary类,实现了Map接口。

**默认容量和扩容策略**

HashTable的初始容量为11,填充因子为0.75,扩容时容量翻倍加1;HashMap的初始容量默认为16,填充因子为0.75,扩容时容量翻倍。

**计算hash的方法**

HashTable直接使用键的hashCode对table数组的长度进行取模计算hash;HashMap使用键的hashCode进行二次hash后对table数组长度取模。

**底层实现**

两者底层实现都是数组+链表结构。

**性能**

由于HashTable是线程安全的,所以在多线程环境下性能较低;HashMap在单线程环境下性能较好,但在多线程环境下需要通过额外的同步措施或使用ConcurrentHashMap来提高性能。

**方法**

HashMap去掉了HashTable的contains方法,改为提供containsValue和containsKey方法,因为contains方法容易让人误解。

总结来说,HashMap的非线程安全和允许null值方面提供了更好的灵活性,而HashTable提供了线程安全和更强的类型安全保证,但牺牲了一定的性能和灵活性。

# HashSet

HashSet 底层是HashMap,HashMap底层是(数组+链表+红黑树)

添加一个元素时,先得到hash值,会转成 -> 索引值

找到存储数据表table,看这个索引位置是否已经存放了元素

如果没有存放,则直接添加

如果存放了,调用 equals() 比较,如果相同,就放弃添加,如果不相同,则添加到最后

在java8中,如果一条 链表 的元素个数 大于 TREEIFY_THRESHOLD(默认是8)(链表准备添加第九个的时候) ,并且 table 的大小 >= MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树)

扩容和哈希表一样

负载因子0.75

当前数组长度 > 容量 * 0.75时,就会触发扩容

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值