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