源码分析四(HashMap与HashTable的区别 )

这一节看一下HashMap与HashTable这两个类的区别,工作一段时间的程序员都知道,

hashmap是非线程安全的,而且key值和value值允许为null,而hashtable是非线程安全的,key和

value都不能为null,hashmap类所属方法没有synchronized修饰,源码如下:

获取map集合元素数量:

1  public int size() {
2         return size;
3     }

判断map集合是否为空:

1  public boolean isEmpty() {
2         return size == 0;
3     }

根据key值查询Value,由下面的方法可以看出HashMap类中key可以为空

 1 public V get(Object key) {
 2         if (key == null)
 3             return getForNullKey();
 4         int hash = hash(key.hashCode());
 5         for (Entry<K,V> e = table[indexFor(hash, table.length)];
 6              e != null;
 7              e = e.next) {
 8             Object k;
 9             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
10                 return e.value;
11         }
12         return null;
13     }

 

而Hashtable的方法是由synchronized修饰的,所以是线程安全的,源码如下:

获取集合元素数量:

1  public synchronized int size() {
2     return count;
3     }

判断集合是否为空:

1 public synchronized boolean isEmpty() {
2     return count == 0;
3     }

判断是否包含这个元素的值:

1  public synchronized boolean contains(Object value) {
2     if (value == null) {
3         throw new NullPointerException();
4     }

所以HashMap与Hashtable的第一个区别是Hashmap是非线程安全的,而hashtable是线程安全的。

 

第二个区别是Hashmap允许key和value的值为空,而hashtable不允许key或者value的值为null

通过如下方法可以看出:

HashMap:key可以为null

 1  public V get(Object key) {
 2         if (key == null)
 3             return getForNullKey();
 4         int hash = hash(key.hashCode());
 5         for (Entry<K,V> e = table[indexFor(hash, table.length)];
 6              e != null;
 7              e = e.next) {
 8             Object k;
 9             if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
10                 return e.value;
11         }
12         return null;
13     }

value可以为空:

 1  public boolean containsValue(Object value) {
 2     if (value == null)
 3             return containsNullValue();
 4 
 5     Entry[] tab = table;
 6         for (int i = 0; i < tab.length ; i++)
 7             for (Entry e = tab[i] ; e != null ; e = e.next)
 8                 if (value.equals(e.value))
 9                     return true;
10     return false;
11     }

 

Hashtable:value不可以为空

 1   public synchronized boolean contains(Object value) {
 2     if (value == null) {
 3         throw new NullPointerException();
 4     }
 5 
 6     Entry tab[] = table;
 7     for (int i = tab.length ; i-- > 0 ;) {
 8         for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
 9         if (e.value.equals(value)) {
10             return true;
11         }
12         }
13     }
14     return false;
15     }

key不能为空,否则会抛空指针异常:

 1  public synchronized V remove(Object key) {
 2     Entry tab[] = table;
 3     int hash = key.hashCode();
 4     int index = (hash & 0x7FFFFFFF) % tab.length;
 5     for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
 6         if ((e.hash == hash) && e.key.equals(key)) {
 7         modCount++;
 8         if (prev != null) {
 9             prev.next = e.next;
10         } else {
11             tab[index] = e.next;
12         }
13         count--;
14         V oldValue = e.value;
15         e.value = null;
16         return oldValue;
17         }
18     }
19     return null;
20     }

 

posted @ 2014-10-15 21:09  warrior1234  阅读(298)  评论(0编辑  收藏  举报