1. HashMap
HashMap初始化的方式有四种。
创建一个Entry数组,默认初始长度为16,当大于0.75的时候,扩展为当前的2倍。有4中初始化map的方式。
Map<String,String> map =
new
HashMap<String, String>();
Map<String,String> map2 =
new
HashMap<String, String>(17);
Map<String,String> map3 =
new
HashMap<String, String>(15, 2f);
Map<String,String> map4 =
new
HashMap<String, String>(map);
map3中的入参,当不传入时,默认是
initialCapacity=
16,
loadFactor=
0.75.当
loadFactor大于1时,会出现当size大于数组长度后依然不扩展数组,这样会导致数组中已存在的Entry对象的next值不是null,调用get方法时,需要遍历,导致性能变慢。当
initialCapacity传入时,数组的长度也不是
initialCapacity,而是大于
initialCapacity的最小的2的N次方。
put方法中,当
e.
hash
== hash && ((k = e.
key
) == key || key.equals(k))时,会覆盖之前的value。所以,如果key的类重写了equals方法,而没有重新hashcode方法,可能会导致不覆盖之前的value。get/put等方法不是同步方法,是非线程安全的。
2. LinkedHashMap
LinkedHashMap继承自HashMap。比HashMap多了一个Entry header。Entry类也比HashMap多了before和after,用来记录存入的顺序,所以LinkedHashMap中的table其实是一个存在数组中的链表。所以LinkedHashMap是有序的。在数组中的顺序与HashMap是一致的,get和put方法也于HashMap一致。
3. HashTable
HashTable与HashMap初始化方式一致,只是默认的
initialCapacity=11.HashTable中的get/put等方法是同步方法。是线程安全的。
总结:相比LinkedHashMap,HashMap无序,但是节省内存,相比HashTable,HashMap是非线程安全的,所以效率比较高。
hash方法写的很简单,还有indexFor方法,应该算是hash算法吧,但是完全看不明白。