java面試必須掌握的技術點--基礎篇--(四)

集合

ArrayList 與 Vector 區別
ArrayList是最常用的List實現類,內部是通過數組實現的,它允許對元素進行快速隨機訪問。數組的缺點是每個元素之間不能有間隔,當數組大小不滿足時需要增加存儲能力,就要講已經有數組的數據複製到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時,需要對數組進行復制、移動、代價比較高。因此,它適合隨機查找和遍歷,不適合插入和刪除。
Vector與ArrayList一樣,也是通過數組實現的,不同的是它支持線程的同步,即某一時刻只有一個線程能夠寫Vector,避免多線程同時寫而引起的不一致性,但實現同步需要很高的花費,因此,訪問它比訪問ArrayList慢。
LinkedList是用鏈表結構存儲數據的,很適合數據的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List接口中沒有定義的方法,專門用於操作表頭和表尾元素,可以當作堆棧、隊列和雙向隊列使用。
ArrayList在內存不夠時默認是擴展50% + 1個,Vector是默認擴展1倍。
Vector提供indexOf(obj, start)接口,ArrayList沒有。
Vector屬於線程安全級別的,但是大多數情況下不使用Vector,因爲線程安全需要更大的系統開銷。
HashMap 和 Hashtable 的區別
HashMap 不是線程安全的
HashMap 是 map 接口的實現類,是將鍵映射到值的對象,其中鍵和值都是對象,並且不能包含重複鍵,但可以包含重複值。HashMap 允許 null key 和 null value,而 HashTable 不允許。

HashTable 是線程安全 Collection。
HashMap 是 HashTable 的輕量級實現,他們都完成了Map 接口,主要區別在於 HashMap 允許 null key 和 null value,由於非線程安全,效率上可能高於 Hashtable。

區別如下:

HashMap允許將 null 作爲一個 entry 的 key 或者 value,而 Hashtable 不允許。
HashMap 把 Hashtable 的 contains 方法去掉了,改成 containsValue 和 containsKey。因爲 contains 方法容易讓人引起誤解。
HashTable 繼承自 Dictionary 類,而 HashMap 是 Java1.2 引進的 Map interface 的一個實現。
HashTable 的方法是 Synchronize 的,而 HashMap 不是,在多個線程訪問 Hashtable 時,不需要自己爲它的方法實現同步,而 HashMap 就必須爲之提供外同步。
Hashtable 和 HashMap 採用的 hash/rehash 算法都大概一樣,所以性能不會有很大的差異。
HashSet 和 HashMap 區別
*HashMap*    *HashSet*
HashMap實現了Map接口    HashSet實現了Set接口
HashMap儲存鍵值對    HashSet僅僅存儲對象
使用put()方法將元素放入map中    使用add()方法將元素放入set中
HashMap中使用鍵對象來計算hashcode值    HashSet使用成員對象來計算hashcode值,對於兩個對象來說hashcode可能相同,所以equals()方法用來判斷對象的相等性,如果兩個對象不同的話,那麼返回false
HashMap比較快,因爲是使用唯一的鍵來獲取對象    HashSet較HashMap來說比較慢
HashMap 和 ConcurrentHashMap 的區別
Hashmap的key和value都可以爲null, 是非線程安全的,存儲的是鍵值對;

hashmap是基於哈希的原理,put存入鍵值對時,會對鍵調用 hashCode()方法,返回的hashcode用於找到bucket位置來存儲Entry對象,hashMap是在bucket中儲存鍵對象和值對象。當兩個對象的hashcode相同時,代表他們的bucket位置相同,此時會發生“碰撞”。因爲hashmap 是使用鏈表存儲對象,所以這個對象會存儲在鏈表中。那麼兩個對象的hashcode相同時,get方法獲取對象是如何操作的呢?會根據鍵值找到bucket存儲位置,在遍歷鏈表調用keys.equals()找到鏈表中正確的節點,最終找到要找的值對象。(這裏能夠遍歷獲取正確的值是因爲鏈表中存儲的是鍵值對)

通過採用合適的equal()和hashcode()將會減少碰撞的發生,提高效率。

hashmap默認的負載因子大小是0.75,即當一個map填滿了75%的bucket時,和其他集合(如Arraylist)一樣,將會創建原來hashmap大小的兩倍的bucket數組,來重新調整map的大小。並將原來的對象放入新的bucket數組中。在重新調整hashmap大小中存在哪些問題呢?在多線程條件下會存在條件競爭。因爲如果兩個線程都發現HashMap需要重新調整大小了,他們就會同時試着調整大小。在調整大小的過程中,存儲在鏈表中的元素次序會反過來,因爲移動到新的bucket位置時,hashmap並不會將元素放在鏈表的尾部,而是放在頭部,如果條件競爭了,就會死循環。所以多線程慎用hashmap。所以concurrentHashmap應運而生。
————————————————
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章