1. 程式人生 > >Java常見面試題及答案 21-30(集合類)

Java常見面試題及答案 21-30(集合類)

21.HashMap的工作原理是什麼?

HashMap內部是通過一個數組實現的,只是這個陣列比較特殊,數組裡儲存的元素是一個Entry實體(jdk 8為Node),這個Entry實體主要包含key、value以及一個指向自身的next指標。HashMap是基於hashing實現的,當我們進行put操作時,根據傳遞的key值得到它的hashcode,然後再用這個hashcode與陣列的長度進行模運算,得到一個int值,就是Entry要儲存在陣列的位置(下標);當通過get方法獲取指定key的值時,會根據這個key算出它的hash值(陣列下標),根據這個hash值獲取陣列下標對應的Entry,然後判斷Entry裡的key,hash值或者通過equals()比較是否與要查詢的相同,如果相同,返回value,否則的話,遍歷該連結串列(有可能就只有一個Entry,此時直接返回null),直到找到為止,否則返回null。
HashMap之所以在每個陣列元素儲存的是一個連結串列,是為了解決hash衝突問題,當兩個物件的hash值相等時,那麼一個位置肯定是放不下兩個值的,於是hashmap採用連結串列來解決這種衝突,hash值相等的兩個元素會形成一個連結串列。

22.HashMap與HashTable的區別是什麼?

1.HashTable基於Dictionary類,而HashMap是基於AbstractMap。Dictionary是任何可將鍵對映到相應值的類的抽象父類,而AbstractMap是基於Map介面的實現,它以最大限度地減少實現此介面所需的工作。(在java 8中我檢視原始碼發現Hashtable並沒有繼承Dictionary,而且裡面也沒有同步方法,是不是java 8中Hashtable不在同步的了?有沒有人解釋一下?)
2. HashMap的key和value都允許為null,而Hashtable的key和value都不允許為null。HashMap遇到key為null的時候,呼叫putForNullKey方法進行處理,而對value沒有處理;Hashtable遇到null,直接返回NullPointerException。
3. Hashtable是同步的,而HashMap是非同步的,但是我們也可以通過Collections.synchronizedMap(hashMap),使其實現同步。

23.CorrentHashMap的工作原理?

jdk 1.6版: ConcurrenHashMap可以說是HashMap的升級版,ConcurrentHashMap是執行緒安全的,但是與Hashtablea相比,實現執行緒安全的方式不同。Hashtable是通過對hash表結構進行鎖定,是阻塞式的,當一個執行緒佔有這個鎖時,其他執行緒必須阻塞等待其釋放鎖。ConcurrentHashMap是採用分離鎖的方式,它並沒有對整個hash表進行鎖定,而是區域性鎖定,也就是說當一個執行緒佔有這個區域性鎖時,不影響其他執行緒對hash表其他地方的訪問。
具體實現: ConcurrentHashMap內部有一個Segment陣列, 該Segment物件可以充當鎖。Segment物件內部有一個HashEntry陣列,於是每個Segment可以守護若干個桶(HashEntry),每個桶又有可能是一個HashEntry連線起來的連結串列,儲存發生碰撞的元素。
每個ConcurrentHashMap在預設併發級下會建立包含16個Segment物件的陣列,每個陣列有若干個桶,當我們進行put方法時,通過hash方法對key進行計算,得到hash值,找到對應的segment,然後對該segment進行加鎖,然後呼叫segment的put方法進行儲存操作,此時其他執行緒就不能訪問當前的segment,但可以訪問其他的segment物件,不會發生阻塞等待。
jdk 1.8版

在jdk 8中,ConcurrentHashMap不再使用Segment分離鎖,而是採用一種樂觀鎖CAS演算法來實現同步問題,但其底層還是“陣列+連結串列->紅黑樹”的實現。

24.遍歷一個List有哪些不同的方式?

    List<String> strList = new ArrayList<>();
    //for-each
    for(String str:strList) {
        System.out.print(str);
    }

    //use iterator 儘量使用這種 更安全(fail-fast)
    Iterator<String> it = strList.iterator();
    while(it.hasNext) {
        System.out.printf(it.next());
    }

25.fail-fast與fail-safe有什麼區別?

Iterator的fail-fast屬性與當前的集合共同起作用,因此它不會受到集合中任何改動的影響。Java.util包中的所有集合類都被設計為fail->fast的,而java.util.concurrent中的集合類都為fail-safe的。當檢測到正在遍歷的集合的結構被改變時,Fail-fast迭代器丟擲ConcurrentModificationException,而fail-safe迭代器從不丟擲ConcurrentModificationException。

26.Array和ArrayList有何區別?什麼時候更適合用Array?

  1. Array可以容納基本型別和物件,而ArrayList只能容納物件。
  2. Array是指定大小的,而ArrayList大小是固定的

27.哪些集合類提供對元素的隨機訪問?

ArrayList、HashMap、TreeMap和HashTable類提供對元素的隨機訪問。

28.HashSet的底層實現是什麼?

通過看原始碼知道HashSet的實現是依賴於HashMap的,HashSet的值都是儲存在HashMap中的。在HashSet的構造法中會初始化一個HashMap物件,HashSet不允許值重複,因此,HashSet的值是作為HashMap的key儲存在HashMap中的,當儲存的值已經存在時返回false。

29.LinkedHashMap的實現原理?

LinkedHashMap也是基於HashMap實現的,不同的是它定義了一個Entry header,這個header不是放在Table裡,它是額外獨立出來的。LinkedHashMap通過繼承hashMap中的Entry,並新增兩個屬性Entry before,after,和header結合起來組成一個雙向連結串列,來實現按插入順序或訪問順序排序。LinkedHashMap定義了排序模式accessOrder,該屬性為boolean型變數,對於訪問順序,為true;對於插入順序,則為false。一般情況下,不必指定排序模式,其迭代順序即為預設為插入順序。

30.LinkedList和ArrayList的區別是什麼?

  1. ArrayList是基於陣列實現,LinkedList是基於連結串列實現
  2. ArrayList在查詢時速度快,LinkedList在插入與刪除時更具優勢

ps:不對的請大家指出來.