Java HashMap 和 Hashtable 区别

你有没有过这样的经历:想把家里的零食按种类分类放——薯片放盒子A,饼干放盒子B,饮料放盒子C,找的时候直接去对应盒子拿,不用翻遍整个屋子。在编程世界里,Java里的HashMap和Hashtable,就像是两种不同的“零食收纳盒”,虽然都是用来存“键值对”(比如把零食种类当“键”,零食位置当“值”),但脾气和用法差别还真不小,今天就用生活化的例子给你讲明白。

第一个区别:能不能放“空零食”?

先想个场景:你家可能有个空盒子,专门用来放“没开封的试吃装”,或者干脆有个空盒子当“临时放东西的地方”。但另一种盒子,要求必须装东西,空了就不能用,甚至不能放“没贴标签的东西”。

Java HashMap 和 Hashtable 区别

HashMap就像前者:它既可以放“空标签”(也就是键为null),也可以放“空零食”(值为null)。比如你想临时记个“没确定名字的零食”,或者“没找到位置的零食”,往HashMap里塞完全没问题,不会报错。

但Hashtable不一样,它就像那种要求“每样东西必须贴标签、必须有实物”的收纳盒——键和值都不能是null。要是你往里面放一个null键,它会直接抛出异常,就像你拿个没贴标签的空盒子去装东西,会被收纳盒主人拦下来。

第二个区别:谁来管“收纳秩序”?

家里的零食收纳盒,有的是你自己整理,放东西、拿东西全靠你手动,不用跟邻居打招呼;有的是小区统一管理的储物柜,你开门放东西、拿东西都需要刷卡或者输密码,而且同一时间只能一个人用,不然容易乱套。

HashMap就是“自助收纳盒”,它不是线程安全的——简单说就是,多个“人”(程序线程)同时往里面放东西,可能会乱。比如你和你弟同时往HashMap里加零食,他刚放了一半,你就加了新的,最后可能某样零食的位置被搞错了,甚至可能出现“放进去找不到”的情况。这种情况适合单线程的场景,比如你自己写个小工具,不需要多个人同时操作。

而Hashtable是“小区统一管理的储物柜”,它的每个操作都加了同步锁,相当于“每次只能一个人用”,多线程同时操作也不会乱。但缺点也很明显:锁会拖慢速度,就像你排队等储物柜,总比自己家的盒子用起来慢一点。所以如果是单线程场景,用Hashtable就有点“大材小用”,浪费性能。

第三个区别:出现时间和用法细节

再说说它们的“出生时间”:Hashtable是Java最早期的类,刚推出的时候,大家只能用它来存键值对。后来Java 1.2的时候,HashMap才正式登场,算是Hashtable的“升级版”,优化了很多地方,比如性能更好,还加了不少实用的方法,比如遍历的时候更方便。

另外,它们的“命名规则”也藏着细节:Hashtable的名字里带“Table”,说明它早期是用数组+链表的结构实现的,和现在HashMap的底层结构(数组+链表/红黑树)有点像,但HashMap后来优化了哈希冲突的处理,效率更高。还有个小细节:HashMap的迭代器是“快速失败”的,意思是如果遍历的时候有人修改了它,会立刻报错,避免出现数据混乱;而Hashtable的迭代器没那么严格,不过现在很少有人用它了,毕竟HashMap的升级版更实用。

其实不管是HashMap还是Hashtable,核心都是用来存“键值对”的工具,就像你家的收纳盒,没有绝对的好坏,选哪个全看你的需求:如果是单线程、追求速度,选HashMap;如果是多线程场景,需要保证安全,那再考虑Hashtable,不过现在更推荐用ConcurrentHashMap来处理多线程的键值对存储,它比Hashtable的性能更好。

上一篇 JavaScript JSON 和对象怎么转换