从源码学习Hashset和Hashtable (2)

 

从源码学习Hashset和Hashtable

HashTable和HashMap的比较

1.HashTable 基于 Dictionary 类,而 HashMap 是基于 AbstractMap。Dictionary 是任何可将键映射到相应值的类的抽象父类, AbstractMap 是基于 Map 接口的实现,但hashtable和hashmap二者都实现了Map接口

2.hashmap可以放键和值均为null的值,但是这样的值你也只能放一个进去,所以hashmap中判断是否存在某个键要用containskey(键必定是唯一的),而不能用get,因此能有多个键对应的value都是null,而hashtable的键和值不可以为null,否则将会报空指针错误

hashmap的处理:

从源码学习Hashset和Hashtable

所以hashmap考虑到了这种key为null的情况,让其hash算出来为0,不为null的key再调用object的hashcode方法算hash

hashmap的get方法如下图,不存在也有可能返回null或者键的值为null,无法判断

从源码学习Hashset和Hashtable

hashtable的处理:

hashtable的设计并没有考虑这么多,而是直接调用其key的hashcode,那么null.hashcode,必将报错

 

从源码学习Hashset和Hashtable

hashtable将检测放入的键对应的值是否为null

 

 

从源码学习Hashset和Hashtable

3.hashmap在默认情况下是非线程安全的,而hashtable以为基本public方法都是用synchronized修饰的,因此其为同步的

4.两者的扩容方式不一样,hashmap扩容是resize方法,容量变为old*2,而hashtable是rehash方法,容量变为old*2+1,

从源码学习Hashset和Hashtable

5.两者内部遍历实现不一样:

hashmap的键值遍历为iterator

从源码学习Hashset和Hashtable

 

hashtable的键值遍历为Enumerator

从源码学习Hashset和Hashtable

 

 6.获取键所在的位置时的方法不同:

hashmap中首先用与逻辑代替了模运算加快了速度,2的n次方-1位全1二进制位再与key的hash与算出键值对的位置,并且其hash值并不是单纯的hashcode,而是用到了key的hashcode的高16位来做异或运算

从源码学习Hashset和Hashtable

 

 

从源码学习Hashset和Hashtable

 

 hashtable中是根据key直接算一个hashcode(可能为负值),然后再和2的31次方-1做与算出来的正值再模当前hash表的长度,然后确定键值对的位置,那么取模的效率肯定没有与逻辑的运行效率更高

从源码学习Hashset和Hashtable

 

参考

https://blog.csdn.net/fujiakai/article/details/51585767 hashmap和hashtable区别

https://wiki.jikexueyuan.com/project/java-collection/hashtable.html hashmap实现原理

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzgdzy.html