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

时间:2023-03-10 00:28:23
源码分析四(HashMap与HashTable的区别 )

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

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

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

获取map集合元素数量:

  public int size() {
return size;
}

判断map集合是否为空:

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

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

 public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}

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

获取集合元素数量:

  public synchronized int size() {
return count;
}

判断集合是否为空:

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

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

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

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

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

通过如下方法可以看出:

HashMap:key可以为null

  public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}

value可以为空:

  public boolean containsValue(Object value) {
if (value == null)
return containsNullValue(); Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
return true;
return false;
}

Hashtable:value不可以为空

   public synchronized boolean contains(Object value) {
if (value == null) {
throw new NullPointerException();
} Entry tab[] = table;
for (int i = tab.length ; i-- > 0 ;) {
for (Entry<K,V> e = tab[i] ; e != null ; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}

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

  public synchronized V remove(Object key) {
Entry tab[] = table;
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
if ((e.hash == hash) && e.key.equals(key)) {
modCount++;
if (prev != null) {
prev.next = e.next;
} else {
tab[index] = e.next;
}
count--;
V oldValue = e.value;
e.value = null;
return oldValue;
}
}
return null;
}