博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HashTable和HashMap的区别
阅读量:6637 次
发布时间:2019-06-25

本文共 7505 字,大约阅读时间需要 25 分钟。

 

继承的父类不同:

* @since JDK1.0 */public class Hashtable
extends Dictionary
implements Map
, Cloneable, java.io.Serializable {

 

* @since   1.2 */public class HashMap
extends AbstractMap
implements Map
, Cloneable, Serializable{

 

初始数组长度不同:

/**     * Constructs a new, empty hashtable with a default initial capacity (11)     * and load factor (0.75).     */    public Hashtable() {    this(11, 0.75f);    }
/**     * Constructs an empty HashMap with the default initial capacity     * (16) and the default load factor (0.75).     */    public HashMap() {        this.loadFactor = DEFAULT_LOAD_FACTOR;        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);        table = new Entry[DEFAULT_INITIAL_CAPACITY];        init();    }

 

方法时否是同步的:

key是否可以是null:HashMap可以,HashTable不可以
value是不可以是null,HashMap可以,HashTable不可以

 
/**     * Maps the specified key to the specified     * value in this hashtable. Neither the key nor the     * value can be null. 

* * The value can be retrieved by calling the get method * with a key that is equal to the original key. * * @param key the hashtable key * @param value the value * @return the previous value of the specified key in this hashtable, * or null if it did not have one * @exception NullPointerException if the key or value is * null * @see Object#equals(Object) * @see #get(Object) */ 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; for (Entry

e = tab[index] ; e != null ; e = e.next) { if ((e.hash == hash) && e.key.equals(key)) { V old = e.value; e.value = value; return old; } } modCount++; if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash(); tab = table; index = (hash & 0x7FFFFFFF) % tab.length; } // Creates the new entry. Entry
e = tab[index]; tab[index] = new Entry
(hash, key, value, e); count++; return null; }

HashMap: /**     * Associates the specified value with the specified key in this map.     * If the map previously contained a mapping for the key, the old     * value is replaced.     *     * @param key key with which the specified value is to be associated     * @param value value to be associated with the specified key     * @return the previous value associated with key, or     *         null if there was no mapping for key.     *         (A null return can also indicate that the map     *         previously associated null with key.)     */    public V put(K key, V value) {        if (key == null)            return putForNullKey(value);        int hash = hash(key.hashCode());        int i = indexFor(hash, table.length);        for (Entry
e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }

 

HashTable:
如果value是null,则会抛NullPointerException    /**     * Returns a string representation of this Hashtable object     * in the form of a set of entries, enclosed in braces and separated     * by the ASCII characters "" (comma and space). Each     * entry is rendered as the key, an equals sign =, and the     * associated element, where the toString method is used to     * convert the key and element to strings.     *     * @return  a string representation of this hashtable     */    public synchronized String toString() {    int max = size() - 1;    if (max == -1)        return "{}";    StringBuilder sb = new StringBuilder();    Iterator
> it = entrySet().iterator(); sb.append('{'); for (int i = 0; ; i++) { Map.Entry
e = it.next(); K key = e.getKey(); V value = e.getValue(); sb.append(key == this ? "(this Map)" : key.toString()); sb.append('='); sb.append(value == this ? "(this Map)" : value.toString()); if (i == max) return sb.append('}').toString(); sb.append(", "); } }

 

put和get时计算hash值的算法不同:

HashTable直接使用了hashCode()方法的值;

HashMap:    public V put(K key, V value) {        if (key == null)            return putForNullKey(value);        int hash = hash(key.hashCode());
HashMap:    /**     * Applies a supplemental hash function to a given hashCode, which     * defends against poor quality hash functions.  This is critical     * because HashMap uses power-of-two length hash tables, that     * otherwise encounter collisions for hashCodes that do not differ     * in lower bits. Note: Null keys always map to hash 0, thus index 0.     */    static int hash(int h) {        // This function ensures that hashCodes that differ only by        // constant multiples at each bit position have a bounded        // number of collisions (approximately 8 at default load factor).        h ^= (h >>> 20) ^ (h >>> 12);        return h ^ (h >>> 7) ^ (h >>> 4);    }

 

HashTable:    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;

 

 

扩容的大小不同:

HashTable  /**     * Increases the capacity of and internally reorganizes this     * hashtable, in order to accommodate and access its entries more     * efficiently.  This method is called automatically when the     * number of keys in the hashtable exceeds this hashtable's capacity     * and load factor.     */    protected void rehash() {    int oldCapacity = table.length;    Entry[] oldMap = table;    int newCapacity = oldCapacity * 2 + 1;    Entry[] newMap = new Entry[newCapacity];    modCount++;    threshold = (int)(newCapacity * loadFactor);    table = newMap;    for (int i = oldCapacity ; i-- > 0 ;) {        for (Entry
old = oldMap[i] ; old != null ; ) { Entry
e = old; old = old.next; int index = (e.hash & 0x7FFFFFFF) % newCapacity; e.next = newMap[index]; newMap[index] = e; } } }

 

HashMap    /**     * Adds a new entry with the specified key, value and hash code to     * the specified bucket.  It is the responsibility of this     * method to resize the table if appropriate.     *     * Subclass overrides this to alter the behavior of put method.     */    void addEntry(int hash, K key, V value, int bucketIndex) {    Entry
e = table[bucketIndex]; table[bucketIndex] = new Entry
(hash, key, value, e); if (size++ >= threshold) resize(2 * table.length); }

 

http://my.oschina.net/placeholder/blog/180069

http://blog.csdn.net/chenssy/article/details/22896871 

 

你可能感兴趣的文章
C#类型之间的转换
查看>>
C#explicit explicit 类型转换
查看>>
C#foreach的原理
查看>>
C#基础值参数和引用参数的运行原理分析
查看>>
C#的扩展方法
查看>>
unity单利模板
查看>>
C#状态模式
查看>>
C# 关于C#中派生类调用基类构造函数的理解
查看>>
外观模式
查看>>
中介者模式
查看>>
桥接模式
查看>>
策略模式
查看>>
unity有限状态机FSMstate(Finite-state machine )
查看>>
C#this 作为索引器
查看>>
第二章线性表
查看>>
第一章数据结构的研究内容
查看>>
第三章单链表(带有头结点的尾插法实现)
查看>>
栈的顺序存储
查看>>
通过栈Stack实现括号匹配的语法检查
查看>>
队列的顺序存储
查看>>