HashMap与HashTable的区别
本文参照http://www.cnblogs.com/xinzhao/p/5644175.html,因为文章比较长以下是我在原文的基础上进行的知识点的简化终结,另外个人不太适应原文的页面布局,跟喜欢这篇转载博文的布局http://www.importnew.com/24822.html。
HashMap和HashTable有什么不同?在面试和被面试的过程中,我问过也被问过这个问题。
原始博文中主要指出了一下8个方面的区别
- 发布时间没有
- 作者
- 对外接口(重要)
- 实现原理(重要)
- 线程安全性(重要)
- 代码风格
- HashTable已经被废弃了(重要)
- 持续优化
我个人觉得最重要的是实现原理、线程安全性、对外接口和HashTable已经被废弃。当然,没有强调“发布时间”不是不尊重历史,没有强调“作者”不是不尊重前辈,只是面试的时候更多的将能做什么,怎么做的,注意事项放在最重要的位置。
对外接口
HashMap与HashTable都实现了Map、Cloneable、Serializable三个接口。但是HashMap继承自抽象类AbstractMap,而HashTable继承自抽象类Dictionary。其中Dictionary类是一个已经被废弃的类。
HashTable比HashMap多了两个公开方法。一个是elements,这来自于抽象类Dictionary,鉴于该类已经废弃,所以这个方法也就没什么用处了。另一个多出来的方法是contains,这个多出来的方法也没什么用,因为它跟containsValue方法功能是一样的。
所以从公开的方法上来看,这两个类提供的,是一样的功能。都提供键值映射的服务,可以增、删、查、改键值对,可以对建、值、键值对提供遍历视图。支持浅拷贝,支持序列化。
实现原理
实现原理上的差异主要体现在数据结构和算法上。
数据结构
从数据结构上讲二者又是一致的采用了哈希表的结构。
哈希表是一种由数组和链表组成的数据结构,主要用于在大量数据中查找指定的元素,此处有彩蛋https://leetcode-cn.com/problems/two-sum/description/,LeetCode的第一个题就是利用哈希表的一个好例子。
说到哈希表上面的博文中解释的比较浅,这里有一篇博文进行了更加详细的描述
https://www.cnblogs.com/chengxiao/p/6059914.html
我对此片博文的主要内容进行了总结:
- 哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表。
- 哈希冲突(哈希碰撞)是指我们对一个元素进行哈希运算后,得到的一个存储地址,然而进行插入的时候,发现已经被其他的元素占用了。解决哈希冲突的有三种方式,取地址的下一个不冲突的元素、哈希冲突的后对地址进行下一次哈希、哈希地址位置扩展成链表。
算法
初始容量大小不同
HashMap默认初始大小为16
HashTable默认初始大小为11
扩容大小不同
HashMap每次扩容为2n,扩容效率高
HashTable每次扩容为2n+1,分布更均匀
线程安全性
HashMap
HashTable是线程安全的(方法用synchronized修饰)
HashMap不是线程安全的
HashTable已经被废弃了
虽然HashTable是程安全的,但是,java已经不推荐这个类,如果在线程安全的情况下,可以使用HashMap,如果在非线程安全的情况下,要是ConCurrentHashashMap
PS
另外原始博文中提到了Doug Lea,强烈建议打开wiki百科https://en.wikipedia.org/wiki/Doug_Lea,膜拜大神。