这一节看一下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 }