原文来自于:zha-ge.cn/java/52
其实我不是很想和 Hashtable 说再见:一次跟"古董" HashMap 探险的的碎碎念
说起来,这周末本来打算加班摸鱼,愣是在代码里遇见了 HashMap 和 Hashtable 这俩"老熟人"。原本想着这点操作小菜一碟,谁知又不小心掉进了一个老旧的坑里。给各位看官唠唠,这场"熟悉又陌生"的 Hash 家族档案案。
大家都说 HashMap 和 Hashtable 像是一对亲兄弟:名字只差了个 "ble",平时见面也很随意。可真用起来,怎么越来越感觉 Hashtable 像年迈长辈,而 HashMap 则属后浪青年?这俩的代沟,简直开挂。
先列个大表,方便谁以后跟我一样记性差还能偷懒地查查:
特性 | HashMap | Hashtable |
---|---|---|
线程安全 | 否 | 是 |
键/值允许 null | 允许 | 都不允许 |
性能 | 更快 | 有点慢(加锁嘛) |
时代感 | 年轻气盛 | 远古老古董 |
奇葩点滴回忆杀
有次同事用 Hashtable 存数据(真的!还有这种人!),我追问一句:"为啥用 Hashtable 啊老哥?"他说:"听说线程安全!"
我:OK fine,心想本宝宝还不是第一次踩雷......
代码随手敲一段,就这样:
java
Map<String, String> table = new Hashtable<>();
table.put(null, "哈?"); // 啪------NullPointerException
啊这,连 null 都不让我存? HashMap 倒是没人管你:
java
Map<String, String> map = new HashMap<>();
map.put(null, "哈喽世界"); // 完美运行
Hashtable:不让存 null,就是这么自信。HashMap:来吧宝贝,想存啥都行~
踩坑瞬间
说点糗事。
刚入行那会儿,项目里有个配置工具,搜一眼是 Hashtable,心想行呗,老规矩。我不假思索往里 put 空 key,直接炸了:
Exception in thread "main" java.lang.NullPointerException
当场社死。后来问师傅,人家只轻描淡写一句:"谁让你用 Hashtable 了?现在都不用它了。" 哦豁,这才发现原来新项目都是 HashMap+ConcurrentHashMap,Hashtable 是"考古现场"象征......
还有个更坑爹:
你敢在多线程里用 HashMap 存取不加锁?
那就等着看"莫名其妙"丢数据,甚至死循环,简直玄学;Hashtable 则自带 synchronized,妥妥当当,但慢到让人抓狂。
经验启示
说真格的,两招送给后来的小伙伴:
-
拒绝 Hashtable,优雅用 ConcurrentHashMap 或 Collections.synchronizedMap。
线程安全换新姿势,不走 Hashtable 老路。
-
需要允许 null 时,不要想太多,选 HashMap,别犹豫。
好吗?Hashtable 会气死你的。
-
艰难维护老旧代码时,下手之前看清楚 Map 的实现,别掉进"NullPointerException"的陷阱。
唠唠结尾
其实,大部分 Javaer 都已经和 Hashtable "说再见"了。做为一个"考古爱好者"以及"踩坑能手",再次总结:
- HashMap 适合大部分新项目,灵活自由,配合 ConcurrentHashMap 足够应付并发。
- Hashtable,留着给老代码吧,也许还要等着被彻底淘汰。
- 最后:有事没事,看一眼表格,少踩一次雷,工作效率upup!
没啥技术含量,全是实战血泪史。有缘人来看了一乐,没准就能少受一次气,多摸一天鱼。码完,收尾,下班溜了~