HashMap与HashTable的区别

HashMap与HashTable的区别

一,不同点:
1.实现的接口继承的类不同
hashmap:继承AbstractMap类,实现Map接口

extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable

hashtable:继承Dictionary类,实现Map接口

extends Dictionary<K,V>
    implements Map<K,V>, Cloneable, java.io.Serializable 

2.初始数组大小
hashmap:16

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

hashtable:11

public Hashtable() {
        this(11, 0.75f);
    }

3.线程安全性
hashmap:线程安全(synchronized关键字)
hashtable:非线程安全

4.扩容方式:
hashmap:resize(2 * table.length); (2的指数)

resize(2 * table.length);

void resize(int newCapacity) {
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }

        Entry[] newTable = new Entry[newCapacity];
        transfer(newTable, initHashSeedAsNeeded(newCapacity));
        table = newTable;
        threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
    }

hashtable:newCapacity = oldCapacity * 2 + 1
HashMap与HashTable的区别

5.null值处理
HashMap:通过putForNullKey专门处理Key为null的情况(table[0]),key不能重复,value有多个null
HashMap与HashTable的区别
HashTable:Key不能为空,当用null当做Key的时候会抛出java.lang.NullPointerException异常,
因为其在计算Hash的时候调用了key.hashCode();当Key为Null的时候就会抛出异常,而且在put中,并未单独对null进行判断(key不能重复)
HashMap与HashTable的区别

6.hash函数不同
hashtable:

hashSeed ^ k.hashCode()

hashmap:

int h = hashSeed;
if (0 != h && k instanceof String) {
return sun.misc.Hashing.stringHash32((String) k);
}
h ^= k.hashCode();
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);

  1. hashmap:去掉了contains方法,有误导。
    HashTable:有contains()方法:判断value是否存在containsValue()

二,相同:
1.底层数据结构都是数组+链表
2.扩容时机相同

三,性能比较
同时处理10万数据的添加、删除耗时比较,10W、100W、400W、。。。进行测试……

import java.util.HashMap;
import java.util.Hashtable;

/**
 * 描述:同时处理10万数据的添加、删除耗时比较
 *
 * @Author administrator{GINO ZHANG}
 * @Date2018/10/31
 */
public class ExcuteTime {
    public static void main(String[] args) {
        HashMap<Integer, Integer> hashMap = new HashMap<>();
        long Start = System.currentTimeMillis();
        for (int i = 0 ;i<100000;++i){
            hashMap.put(1,1);
        }
        long End = System.currentTimeMillis();
        long Time = End - Start;
        System.out.println(Time+"ms");
        System.out.println();

        Hashtable<Integer, Integer> hashtable = new Hashtable<>();
        long Start1 = System.currentTimeMillis();
        for (int i = 0 ;i<100000;++i){
            hashtable.put(1,1);
        }
        long End1 = System.currentTimeMillis();
        long Time1 = End1 - Start1;
        System.out.println(Time1+"ms");

    }
}

测试结果:

C:\java\java7\jdk1.7.0_80\bin\java.exe -javaagent:D:\ideaIU-2018.1.5.win\lib\idea_rt.jar=6574:D:\ideaIU-2018.1.5.win\bin -Dfile.encoding=UTF-8 -classpath 
9ms

17ms

Process finished with exit code 0

结论:

HashMap要比HashTable快(单线程)

主要影响是:

HashTable是线程安全的,使用了同步操作关键字Synchronize,
而Synchronize关键字是一个重量级锁,涉及用户空间可内核空间的切换,影响性能的点
long l = System.currentTimeMillis();//当前时间毫秒数