HsahMap HashTable底层实现&异同

来源:互联网 发布:庇古的福利经济学知乎 编辑:程序博客网 时间:2024/06/06 02:54

HsahMap HashTable底层实现

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

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

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

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

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

[java] view plaincopyHashtable table = new Hashtable();  table.put("a-key", "a-value");  table.put("b-key", "b-value");  table.put("c-key", "c-value");  [java] view plain copyHashtable table = new Hashtable();  table.put("a-key", "a-value");  table.put("b-key", "b-value");  table.put("c-key", "c-value");  输出如下:[java] view plaincopya-key - a-value  c-key - c-value  b-key - b-value  [java] view plain copya-key - a-value  c-key - c-value  b-key - b-value  

再看个Hashtable拒绝null的示例:

[java] view plaincopytable.put(null, "a-value");  [java] view plain copytable.put(null, "a-value");  

运行之后异常如下:

[java] view plaincopyException in thread "main"  java.lang.NullPointerException  at java.util.Hashtable.put(Hashtable.java:399)  at com.darkmi.sandbox.HashtableTest.main(HashtableTest.java:20)  [java] view plain copyException in thread "main" java.lang.NullPointerException  at java.util.Hashtable.put(Hashtable.java:399)  at                    com.darkmi.sandbox.HashtableTest.main(HashtableTest.java:20)  

HashMap示例:

[java] view plaincopyHashMap map = new HashMap();  map.put(null, "a-value");  map.put("b-key", null);  map.put("c-key", null);  [java] view plain copyHashMap map = new HashMap();  map.put(null, "a-value");  map.put("b-key", null);  map.put("c-key", null);  

运行之后,输出如下:

[java] view plaincopyb-key - null  null - a-value  c-key - null  [java] view plain copyb-key - null  null - a-value  c-key - null  

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

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

[java] view plaincopyEnumeration em = table.elements();  while (em.hasMoreElements()) {  String obj = (String) em.nextElement();  System.out.println(obj);   }  [java] view plain copyEnumeration em = table.elements();  while (em.hasMoreElements()) {  String obj = (String) em.nextElement();  System.out.println(obj);   }  

Hashtable 和 HashMap 都能通过values()方法返回一个

Collection ,然后进行遍历处理:[java] view plaincopyCollection coll = map.values();  Iterator it = coll.iterator();  while (it.hasNext()) {  String obj = (String) it.next();  System.out.println(obj);  }  [java] view plain copyCollection coll = map.values();  Iterator it = coll.iterator();  while (it.hasNext()) {  String obj = (String) it.next();  System.out.println(obj);  }  

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

[java] view plaincopySet set = table.entrySet();  Iterator it = set.iterator();  while (it.hasNext()) {  Entry entry = (Entry) it.next();  System.out.println(entry.getKey() + " - " + entry.getValue());  }  [java] view plain copySet 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,代码是这样的:

[java] view plaincopyint hash = key.hashCode();  int index = (hash & 0x7FFFFFFF) % tab.length;  [java] view plain copyint hash = key.hashCode();  int index = (hash & 0x7FFFFFFF) % tab.length;  

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

[java] view plaincopyint 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);  [java] view plain copyint 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);  
0 0
原创粉丝点击