HashMap的小记
hashMap和hashTable的几点区别:
1.hashMap继承的是AbstractMap类,hashTable继承的是Dictionary。
2.hashMap是线程不安全的,hashTable是线程安全的。由他们的源码可以看出:
hashMap:
public V put(K key, V value){
}
HashTable:
public synchronized V put(K key, V value){
}
很明显看出,HashTable的put的同步的,也就是说当它进行put操作时,如果有其他线程对要进行put,就必须要等前一个put操作完,才能进行下个put。而HashMap要实现同步可以使用Colletcions进行同步Map Collections.synchronizedMap(Map m)。
3.HashMap能put(null,null)。而HashTable的key和value都不能为空。同样由它们的源码可以看出:
HashTable的put方法中
if (value == null) {
throw new NullPointerException();
}
当value为null时,就抛出空指针异常。当key为空时,key.hashCode()就抛出空指针异常,计算key的hash值时报错。
HashMap的put方法中
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
对key为null有单独的处理,这时候会的hash值赋为0。
4.HashMap和HashTable在计算hash值时,也有细微的不同。从上面的代码可以看出,HashMap的hash值hash(key.hashCode()),HashTable就直接是key.hashCode()。
HashMap的实现原理:
当Map<String, String> map = new HashMap<String, String>(); map.put(“1”,”1”);
1.new一个HashMap时,会创建一个Entry[] table,它就是用来存储Map的每一个key-value对。table的初始大少为16。
2.当进行put操作时,首先根据key来计算hash值,如果key为null,它的hash值会设为0,根据这个hash值在来计算它的table中的位置。Entry<K,V> e = table[i],如果e为null,就说明这个key是一个新值,就进行addEntry方法,将这对key-value放入Entry,再将这个Entry放入table中;如果e不为null,就会更新value,将之前的value覆盖。
还有一个问题。当计算出的table的索引大于table的长度。Table的size会*2,也就是说table的size永远是2的倍数。