HashTable与HashMap

本文详细对比了Hashtable和HashMap在同步性、null值处理、遍历方式、内部实现机制及哈希值使用上的区别。强调了HashMap作为新框架推荐替代Hashtable的原因,并通过代码示例展示了两者在实际应用中的表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Hashtable的应用非常广泛,HashMap是新框架中用来代替Hashtable的类,也就是说建议使用HashMap,不要使用Hashtable。可能你觉得Hashtable很好用,为什么不用呢?这里简单分析他们的区别。

1.Hashtable的方法是同步的,HashMap未经同步,所以在多线程场合要手动同步HashMap这个区别就像Vector和ArrayList一样。

查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized 关键字,而HashMap的源代码中则连 synchronized 的影子都没有,当然,注释除外。

2.Hashtable不允许 null 值(key 和 value 都不可以),HashMap允许 null 值(key和value都可以)。

先看个Hashtable正常输出的示例:

 
Hashtable table = new Hashtable();

table.put("a-key", "a-value");

table.put("b-key", "b-value");

table.put("c-key", "c-value");
  1.  

输出如下:

 ​​​​​​
a-key - a-value

c-key - c-value

b-key - b-value

再看个Hashtable拒绝null的示例:

table.put(null, "a-value");

运行之后异常如下:

 
Exception in thread "main" java.lang.NullPointerException

at java.util.Hashtable.put(Hashtable.java:399)

at com.darkmi.sandbox.HashtableTest.main(HashtableTest.java:20)

HashMap示例:

 ​​​​​​​
HashMap map = new HashMap();

map.put(null, "a-value");

map.put("b-key", null);

map.put("c-key", null);

运行之后,输出如下:

 ​​​​​​​
b-key - null

null - a-value

c-key - null

 

PS:从上面的示例我们倒是可以发现Hashtable与HashMap相同的一点:无序存放。

3.两者的遍历方式大同小异,Hashtable仅仅比HashMap多一个elements方法。

 
Enumeration em = table.elements();

while (em.hasMoreElements()) {

String obj = (String) em.nextElement();

System.out.println(obj);

}


Hashtable 和 HashMap 都能通过values()方法返回一个 Collection ,然后进行遍历处理:

 ​​​​​​​
Collection coll = map.values();

Iterator it = coll.iterator();

while (it.hasNext()) {

String obj = (String) it.next();

System.out.println(obj);

}

两者也都可以通过 entrySet() 方法返回一个 Set , 然后进行遍历处理:

 ​​​​​​​
Set set = table.entrySet();

Iterator it = set.iterator();

while (it.hasNext()) {

Entry entry = (Entry) it.next();

System.out.println(entry.getKey() + " - " + entry.getValue());


}

 

4.HashTable使用Enumeration,HashMap使用Iterator

 

以下这两点是从内部实现机制上来进行比较,

了解即可:

5.哈希值的使用不同,Hashtable直接使用对象的hashCode,代码是这样的:

 
int hash = key.hashCode();

int index = (hash & 0x7FFFFFFF) % tab.length;

 

而HashMap重新计算hash值,而且用与代替求模:

 ​​​​​​​
int hash = hash(k);

int i = indexFor(hash, table.length);


static int hash(Object x) {

  int h = x.hashCode();


  h += ~(h << 9);

  h ^= (h >>> 14);

  h += (h << 4);

  h ^= (h >>> 10);

  return h;

}


static int indexFor(int h, int length) {

  return h & (length-1);

 

6.Hashtable中hash数组默认大小是11,增加的方式是 old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值