HashMap与HashTable

来源:互联网 发布:应聘软件测试自我介绍 编辑:程序博客网 时间:2024/06/06 02:15

一.Hashtable与HashMap的区别

查看源码我们可以知道:

1. 从类继承来讲--------- HashMap继承于AbstractMap类;HashTable继承于Dictionary类

public class HashMap<K,V> extends AbstractMap<K,V>    implements Map<K,V>, Cloneable, Serializable {}
public class Hashtable<K,V>    extends Dictionary<K,V>    implements Map<K,V>, Cloneable, java.io.Serializable {}


2.从键和值的角度来讲-------------HashMap键和值可以为空,而HashTable不可以

看一下HashMap的源码:hash值可以为null

public V put(K key, V value) {    return putVal(hash(key), key, value, false, true);}

public final int hashCode() {    return Objects.hashCode(key) ^ Objects.hashCode(value);}
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);}

再看一下HashTable的源码:如果值为空抛空指针,计算hashcode方式完全不一样


public synchronized V put(K key, V value) {    // Make sure the value is not null    if (value == null) {        throw new NullPointerException();    }    // Makes sure the key is not already in the hashtable.    Entry<?,?> tab[] = table;    int hash = key.hashCode();    int index = (hash & 0x7FFFFFFF) % tab.length;    @SuppressWarnings("unchecked")    Entry<K,V> entry = (Entry<K,V>)tab[index];    for(; entry != null ; entry = entry.next) {        if ((entry.hash == hash) && entry.key.equals(key)) {            V old = entry.value;            entry.value = value;            return old;        }    }    addEntry(hash, key, value, index);    return null;}

public synchronized int hashCode() {    /*     * This code detects the recursion caused by computing the hash code     * of a self-referential hash table and prevents the stack overflow     * that would otherwise result.  This allows certain 1.1-era     * applets with self-referential hash tables to work.  This code     * abuses the loadFactor field to do double-duty as a hashCode     * in progress flag, so as not to worsen the space performance.     * A negative load factor indicates that hash code computation is     * in progress.     */    int h = 0;    if (count == 0 || loadFactor < 0)        return h;  // Returns zero    loadFactor = -loadFactor;  // Mark hashCode computation in progress    Entry<?,?>[] tab = table;    for (Entry<?,?> entry : tab) {        while (entry != null) {            h += entry.hashCode();            entry = entry.next;        }    }    loadFactor = -loadFactor;  // Mark hashCode computation complete    return h;}


3.从线程安全角度来讲:HashMap是线程安全的,Hashtable是线程非安全的



4. 从初始容量和扩容倍数来讲: HashMap的初始容量为16,Hashtable初始容量为11.两者两者的填充因子默认都是0.75;HashMap扩容时是当前容量翻倍即:2 x capacity,Hashtable扩容时是容量翻倍+1即:capacity*2+1


5.从计算hashcode的方式来讲:

Hashtable计算hash是直接使用key的hashcode对table数组进行取模
HashMap计算hash对key的hashcode进行了二次hash,以获取更好的散列值,然后对table数组长度取模


6.最后送上福利:将HashMap变为线程安全的,不用Hashtable


* HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。
Map map = Collections.synchronizedMap(new HashMap());









1 0
原创粉丝点击