1、map以key-value形式存儲數據。map的實現形式有hashmap,treemap,linkedhashmap等。
hashmap:map基於散列表實現,存儲鍵值順序和插入次序無關,優勢在於查詢速度快。
treemap:放入treemap中的值會根據key按照字母順序排序,與插入順序無關
linkedhashmap:類似於hashmap,查詢速度稍慢,但迭代遍歷速度快,存儲值得順序和插入順序一致。
2、hashmap爲什麼具有查詢速度優勢?
這和hashmap存儲數值的方式有關。hashmap以散列形式存儲元素,hashmap用通過object的hashcode()方法
生成散列碼(默認用對象的地址計算散列碼)。
這裏引入一個桶位的概念,即hashmap用來存儲鍵值對的數組。每次調用hashmap的put(K,V)方法存放元素時,
會首先用鍵對象的hashcode()方法來生成一個散列碼,把這個散列碼作爲數組的下標,把鍵值對一塊存儲在對應的桶位,
每個桶位以鏈表的形式保存鍵值對。這是爲什麼呢?由於不同的對象可能生成相同的散列碼,即不同的對象存儲在
同一個桶位,這時後來的對象就要插入到鏈表的尾部。
查找時使用get(K)方法,根據鍵對象生成的hashcode快速定位到桶位,再用keys.equals()方法線性遍歷對應key
3、覆蓋hashcode()方法
hashmap默認使用的是對象的地址計算散列碼,如果想要使用別的方式計算散列碼,就得重寫hashcode方法,
如string對象就是用string的內容計算散列碼的。用來計算散列碼的值不應該是易變得,否則put()和get()前後得到的
hashcode不一致,無法查詢到。
4、如果HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦?
負載因子是桶中實際存儲的對象數量和最大容量的比值。默認的負載因子大小爲0.75,也就是說,當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)一樣,將會創建原來HashMap大小的兩倍的bucket數組,來重新調整map的大小,並將原來的對象放入新的bucket數組中。這個過程叫作rehashing,因爲它調用hash方法找到新的bucket位置
5、爲什麼String, Interger這樣的wrapper類適合作爲鍵?
String, Interger這樣的wrapper類作爲HashMap的鍵是再適合不過了,而且String最爲常用。因爲String是不可變的,也是final的,而且已經重寫了equals()和hashCode()方法了。其他的wrapper類也有這個特點。不可變性是必要的,因爲爲了要計算hashCode(),就要防止鍵值改變,如果鍵值在放入時和獲取時返回不同的hashcode的話,那麼就不能從HashMap中找到你想要的對象。不可變性還有其他的優點如線程安全。如果你可以僅僅通過將某個field聲明成final就能保證hashCode是不變的,那麼請這麼做吧。因爲獲取對象的時候要用到equals()和hashCode()方法,那麼鍵對象正確的重寫這兩個方法是非常重要的。如果兩個不相等的對象返回不同的hashcode的話,那麼碰撞的機率就會小些,這樣就能提高HashMap的性能。