源码解析hashmap和hashtable区别
概述:
我最开始理解的就是hashTable就是散列表,然后hashMap底层就是散列表,所以hashMap底层是要依靠hashTable的
后面才知道两个md是完全不一样的东西。。。
区别(网上找的)
- 两者父类不同:HashMap继承自AbstractMap类,HashTable继承自Dictionary类
- HashMap是线程不安全的,Hashtable是线程安全的(HashTable的方法大多都是synchronize的)
- hashMap有containsKey(底层直接调用contains()),和containsvalue,而hashTable只有contains
- hashMap是允许key和value都是null的,hashTable键值对都不能为空
- 计算hash值的方式不同
- hashMap在原来的hash值(key.gethashCode())的基础上,重新计算了hash值
- hashtable就直接用key.getHashcode了
hashtable
多的也不用咋看,hashTable在hashMap出来后,就已基本抛弃不用了(由于他的dictionary父类被抛弃)
只要了解底层是由Entry<?,?> table实现的
而这个Entry是在HashTable类实现的一个内部类。
public class Hashtable<K,V> extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable {
//类属性
private transient Entry<?,?>[] table;
private transient int count;
private int threshold;
private float loadFactor;
private transient int modCount = 0;
private static final long serialVersionUID = 1421746759512286392L;
//构造方法
public Hashtable(int initialCapacity, float loadFactor) {}
private static class Entry<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Entry<K,V> next;
protected Entry(int hash, K key, V value, Entry<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
}
hashmap
可以看到hashMap底层实际存储数据的是Node内部类,而node内部类的实现和hashtable的Entry实现是一摸一样的(这里仅指类的属性,方法实现有部分不一样)!
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
private static final long serialVersionUID = 362498820763181265L;
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;
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}