1.线程安全
HashMap是线程不安全,Hashtable是线程安全,
原因:Hashtable线程不安全是因为其源码中的所有元素都是用synchronized同步关键字修饰的,HashMap没有,
2.效率性能优劣
HashMap因为是线程不安全的,所以效率比较高,Hashtable因为是线程安全的,每个方法都要阻塞其他的方法,排队执行,所有效率相比HashMap比较差
如果要线程安全又要保证性能,建议使用 JUC 包下的 ConcurrentHashMap。
3.null值
HashMap允许key和value为null,Hashtable不允许value为null;
HashMap允许为null是因为其对null做了处理,源码如下->
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Hashtable不允许value为null是因为会报空指针异常,源码如下->
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;
}
4.实现方式
HashMap继承的是AbstractMap类,Hashtable继承的是Dictionary类
HashMap 的继承源码:
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
Hashtable 的继承源码:
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
5.容量扩容
HashMap初始容量:16,Hashtable初始容量:11,两个的负载因子都是0.75;
扩容规则:HashMap为翻倍,Hashtable为翻倍+1
HashMap源码如下:
/**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
}
Hashtable源码如下:
/**
* Constructs a new, empty hashtable with a default initial capacity (11)
* and load factor (0.75).
*/
public Hashtable() {
this(11, 0.75f);
}
6.迭代器(Enumeration 和 Iterator 的区别)
HashMap 中的 Iterator 迭代器是 fail-fast 的,而 Hashtable 的 Enumerator 不是 fail-fast 的。
所以,当其他线程改变了HashMap 的结构,如:增加、删除元素,将会抛出 ConcurrentModificationException 异常,而 Hashtable 则不会。
public static void main(String[] args) {
Map<String, String> hashtable = new Hashtable<>();
hashtable.put("t1", "1");
hashtable.put("t2", "2");
hashtable.put("t3", "3");
Enumeration<Map.Entry<String, String>> iterator1 = (Enumeration<Map.Entry<String, String>>) hashtable.entrySet().iterator();
hashtable.remove(iterator1.nextElement().getKey());
while (iterator1.hasMoreElements()) {
System.out.println(iterator1.nextElement());
}
Map<String, String> hashMap = new HashMap<>();
hashMap.put("h1", "1");
hashMap.put("h2", "2");
hashMap.put("h3", "3");
Iterator<Map.Entry<String, String>> iterator2 = hashMap.entrySet().iterator();
hashMap.remove(iterator2.next().getKey());
while (iterator2.hasNext()) {
System.out.println(iterator2.next());
}
}
输出信息:
t2=2
t1=1
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$EntryIterator.next(HashMap.java:1463)
at java.util.HashMap$EntryIterator.next(HashMap.java:1461)
at com.utaka.united.promotion.service.DiscountActivityService.main(DiscountActivityService.java:1338)
如有转载请请务必保留此出处:https://blog.csdn.net/hometing218/article/details/85045285