文章目录
Hashmap和Hashtable的区别和联系
Hashtable
出现于 JDK1.0,是线程安全的集合,底层使用哈希表实现
区别和联系
1.继承和实现
Hashtable
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
Hashmap
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
相同点:都实现了map,Cloneable接口,可序列化接口
不同点:Hashtable继承了 Dictionary类(since 1.0),而 Hashmap实现AbstractMap继而继承map类
Dictionary类和map类类似,都是保存键值对,通过键进行查询,比map类多elements()方法返回(返回Hashtable中值的枚举)。
2.属性
Hashtable
private transient Entry<?,?>[] table;
private transient int count;
private int threshold;
private float loadFactor;
private transient int modCount = 0;
Hashmap
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
static final int MAXIMUM_CAPACITY = 1 << 30;
static final float DEFAULT_LOAD_FACTOR = 0.75f;
static final int TREEIFY_THRESHOLD = 8;
static final int UNTREEIFY_THRESHOLD = 6;
static final int MIN_TREEIFY_CAPACITY = 64;
transient Node<K,V>[] table;
transient Set<Map.Entry<K,V>> entrySet;
transient int size;
transient int modCount;
int threshold;
final float loadFactor;
相较于Hashtable,Hashtable提供了更多的属性更多的选择。Hashtable有效个数用count计数,而HashMap使用size计数
3.构造器
Hashtable
public Hashtable(int initialCapacity) {
this(initialCapacity, 0.75f);
}
public Hashtable() {
this(11, 0.75f);
}
默认初始容量上:
可以看到hashtable默认初始容量为11,而 hashmap初始容量为16,所以这里可以看出Hashtable初始容量可以不是2的幂次方,而Hashmap则会要求一定得是2的幂次方
3.方法
hash()方法
Hashtable所有方法前都加上synchronized,所以是线程安全的 类似于victor容器,带来的后果就是效率低,麻烦
Hashtable
//是直接使用Object类中的hashCode方法
HashMap
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Hashtable是直接使用Object类中的hashCode方法,而 HashMap还进行了加工取模运算,减少了哈希冲突
迭代器
两者都使用了Iterator,但是Hashtable还可以使用Enumerator的方式
Hashtable
private class Enumerator<T> implements Enumeration<T>, Iterator<T>
HashMap
abstract class HashIterator
扩容
Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
key和value是否可以为null
Hashtable
public synchronized boolean containsKey(Object key) {
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)) {
return true;
}
}
return false;
}
public synchronized boolean contains(Object value) {
if (value == null) {
throw new NullPointerException();
}
Entry<?,?> tab[] = table;
for (int i = tab.length ; i-- > 0 ;) {
for (Entry<?,?> e = tab[i] ; e != null ; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}
可以看出key和value是不允许为null的
而HashMap key值可以为空但是编译可以通过 但运行不会通过,value可以为空