JDK 源码复习 util包 04 HashTable && HashSet

HashTable

hashtable的结构图

 

 

说明:

  • 代码块1:为Entry节点中包含的key、value、hash、next。
  • 代码块2:为Entry的构造函数,即把新节点接在了next链表的开头部分。

Hasttable的默认容量(数组大小)为11,默认的负载因子为0.75。同时由代码块2可知数组扩容的阈值threshold=capacity*loadFactory。
注意:hashtable中的数组容量capacity没有限制为2的n次方,取任何大于0的数都行

Hashtable的put操作实现

è¿éåå¾çæè¿°

说明:

代码块1:hashtable之所以是线程安全的,原因为在put和get方法上使用synchronized关键字进行修饰。
代码块2:限制了value不能为null。
代码块3:由于直接使用key.hashcode(),而没有向hashmap一样先判断key是否为null,所以key为null时,调用key.hashcode()会出错,所以hashtable中key也不能为null。
代码块4:hashtable中对hash值进行寻址的方法为hash%数组长度(与hashmap不同,所以不要求数组长度必须为2的n次方)
代码块5:entry=table[index]
代码块6:遍历table[index]所连接的链表,查找是否已经存在key与需要插入的key值相同的节点,如果存在则直接更新value,并返回旧的value。
代码块7:如果table[index]所连接的链表上不存在相同的key,则通过addEntry()方法将新节点加载链表的开头。
 

Hashtable和hashmap的区别总结
1、 hashmap中key和value均可以为null,但是hashtable中key和value均不能为null。

2、 hashmap采用的是数组(桶位)+链表+红黑树结构实现,而hashtable中采用的是数组(桶位)+链表实现。

3、 hashmap中出现hash冲突时,如果链表节点数小于8时是将新元素加入到链表的末尾,而hashtable中出现hash冲突时采用的是将新元素加入到链表的开头。

4、 hashmap中数组容量的大小要求是2的n次方,如果初始化时不符合要求会进行调整,而hashtable中数组容量的大小可以为任意正整数。

5、 hashmap中的寻址方法采用的是位运算按位与,而hashtable中寻址方式采用的是求余数。

6、 hashmap不是线程安全的,而hashtable是线程安全的,hashtable中的get和put方法均采用了synchronized关键字进行了方法同步。

7、 hashmap中默认容量的大小是16,而hashtable中默认数组容量是11。


Hashtable和HashMap扩容的方法不一样,Hashtable中数组默认大小11,扩容方式是 old*2+1。HashMap中数组的默认大小是16,而且一定是2的指数,增加为原来的2倍。
两者通过hash值散列到hash表的算法不一样,Hashtable是古老的除留余数法,直接使用Object的hashcode,而后者是强制容量为2的幂,重新根据hashcode计算hash值,在使用hash和(hash表长度 – 1)进行与运算,也等价取膜,但更加高效,取得的位置更加分散,偶数,奇数保证了都会分散到。前者就不能保证。
HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的。所以当有其它线程改变了HashMap的结构(增加或者移除元素),将会抛出ConcurrentModificationException,但迭代器本身的remove()方法移除元素则不会抛出ConcurrentModificationException异常
 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

HashSet 复习

请说说HashSet原理,并写程序证明
HashSet在存元素时,会调用对象的hashCode方法计算出存储位置,然后和该位置上所有的元素进行equals比较,
如果该位置没有其他元素或者比较的结果都为false就存进去,否则就不存。
这样的原理注定了元素是按照哈希值来找存储位置,所有无序,而且可以保证无重复元素
我们在往HashSet集合存储元素时,对象应该正确重写Object类的hashCode和equals方法
正因为这样的原理,HashSet集合是非常高效的。
比如,要查找集合中是否包含某个对象,首先计算对象的hashCode,折算出位置号,到该位置上去找就可以了,而不用和所有的元素都比较一遍

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

TreeMap 底层原理

文章的内容基于JDK1.7进行分析,之所以选用这个版本,是因为1.8的有些类做了改动,增加了阅读的难度,虽然是1.7,但是对于1.8做了重大改动的内容,文章也会进行说明。

TreeMap实现了SotredMap接口,它是有序的集合。而且是一个红黑树结构,每个key-value都作为一个红黑树的节点。如果在调用TreeMap的构造函数时没有指定比较器,则根据key执行自然排序。这点会在接下来的代码中做说明,如果指定了比较器则按照比较器来进行排序。

TreeSet实现:

  

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值